From 0751e9036af0525c3e42b74cce5597ed66dd7849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Jan 2025 03:26:56 +0000 Subject: [PATCH] Rework "long type names" printing logic Make it so more type-system types can be printed in a shortened version (like `Predicate`s). Centralize printing the information about the "full type name path". Make the "long type path" for the file where long types are written part of `Diag`, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit. Tweak the shortening of types in "expected/found" labels. Remove dead file `note.rs`. --- compiler/rustc_borrowck/messages.ftl | 3 - .../src/diagnostics/conflict_errors.rs | 8 +- .../src/diagnostics/move_errors.rs | 24 +- .../rustc_borrowck/src/session_diagnostics.rs | 7 - compiler/rustc_errors/src/diagnostic.rs | 31 ++ .../rustc_hir_typeck/src/method/suggest.rs | 39 +- compiler/rustc_middle/src/ty/error.rs | 37 +- compiler/rustc_middle/src/ty/print/mod.rs | 4 + compiler/rustc_middle/src/ty/print/pretty.rs | 93 ++-- compiler/rustc_mir_build/messages.ftl | 2 - compiler/rustc_mir_build/src/errors.rs | 4 - .../src/thir/pattern/check_match.rs | 8 +- .../src/error_reporting/infer/mod.rs | 47 +- .../error_reporting/infer/need_type_info.rs | 2 +- .../src/error_reporting/infer/note.rs | 422 ------------------ .../src/error_reporting/infer/region.rs | 10 +- .../src/error_reporting/traits/ambiguity.rs | 20 +- .../traits/fulfillment_errors.rs | 82 ++-- .../src/error_reporting/traits/mod.rs | 11 - .../traits/on_unimplemented.rs | 2 +- .../src/error_reporting/traits/overflow.rs | 11 - .../src/error_reporting/traits/suggestions.rs | 54 +-- .../coerce-expect-unsized-ascribed.stderr | 6 +- tests/ui/diagnostic-width/E0271.ascii.stderr | 8 +- tests/ui/diagnostic-width/E0271.rs | 4 +- .../ui/diagnostic-width/E0271.unicode.stderr | 8 +- .../diagnostic-width/long-E0308.ascii.stderr | 28 +- .../long-E0308.unicode.stderr | 28 +- tests/ui/diagnostic-width/long-e0277.rs | 15 + tests/ui/diagnostic-width/long-e0277.stderr | 23 + .../non-copy-type-moved.stderr | 4 +- .../secondary-label-with-long-type.rs | 2 +- .../secondary-label-with-long-type.stderr | 2 +- .../hang-on-deeply-nested-dyn.stderr | 2 +- .../box-future-wrong-output.stderr | 2 +- .../expected-boxed-future-isnt-pinned.stderr | 2 +- tests/ui/suggestions/issue-107860.stderr | 2 +- .../traits/ice-with-dyn-pointee-errors.stderr | 2 +- tests/ui/traits/object/pretty.stderr | 4 +- .../traits/on_unimplemented_long_types.stderr | 2 - tests/ui/typeck/issue-107775.stderr | 2 +- .../typeck/return_type_containing_closure.rs | 2 +- .../return_type_containing_closure.stderr | 2 +- 43 files changed, 331 insertions(+), 740 deletions(-) delete mode 100644 compiler/rustc_trait_selection/src/error_reporting/infer/note.rs create mode 100644 tests/ui/diagnostic-width/long-e0277.rs create mode 100644 tests/ui/diagnostic-width/long-e0277.stderr diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index c00e6dde91965..ada20e5c614f8 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -92,9 +92,6 @@ borrowck_lifetime_constraints_error = borrowck_limitations_implies_static = due to current limitations in the borrow checker, this implies a `'static` lifetime -borrowck_long_type_consider_verbose = consider using `--verbose` to print the full type name to the console -borrowck_long_type_full_path = the full type name has been written to '{$path}' - borrowck_move_closure_suggestion = consider adding 'move' keyword before the nested closure diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 07dcbba019ade..c6439da33d6d7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -289,8 +289,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { None => "value".to_owned(), }; if needs_note { - let mut path = None; - let ty = self.infcx.tcx.short_ty_string(ty, &mut path); + let ty = self.infcx.tcx.short_string(ty, err.long_ty_path()); if let Some(local) = place.as_local() { let span = self.body.local_decls[local].source_info.span; err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { @@ -306,11 +305,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { place: ¬e_msg, }); }; - if let Some(path) = path { - err.subdiagnostic(crate::session_diagnostics::LongTypePath { - path: path.display().to_string(), - }); - } } if let UseSpans::FnSelfUse { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 14a900f38e922..58c5c2fd7742a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -596,19 +596,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, place_ty, expr, None); } - let mut path = None; - let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path); + let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, ty, place: &place_desc, span, }); - if let Some(path) = path { - err.subdiagnostic(crate::session_diagnostics::LongTypePath { - path: path.display().to_string(), - }); - } } else { binds_to.sort(); binds_to.dedup(); @@ -635,19 +629,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, place_ty, expr, Some(use_spans)); } - let mut path = None; - let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path); + let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, ty, place: &place_desc, span: use_span, }); - if let Some(path) = path { - err.subdiagnostic(crate::session_diagnostics::LongTypePath { - path: path.display().to_string(), - }); - } use_spans.args_subdiag(err, |args_span| { crate::session_diagnostics::CaptureArgLabel::MoveOutPlace { @@ -845,19 +833,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.suggest_cloning(err, bind_to.ty, expr, None); } - let mut path = None; - let ty = self.infcx.tcx.short_ty_string(bind_to.ty, &mut path); + let ty = self.infcx.tcx.short_string(bind_to.ty, err.long_ty_path()); err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { is_partial_move: false, ty, place: place_desc, span: binding_span, }); - if let Some(path) = path { - err.subdiagnostic(crate::session_diagnostics::LongTypePath { - path: path.display().to_string(), - }); - } } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 2c37d2bc12362..11b30c145c2c2 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -458,13 +458,6 @@ pub(crate) enum OnClosureNote<'a> { }, } -#[derive(Subdiagnostic)] -#[note(borrowck_long_type_full_path)] -#[note(borrowck_long_type_consider_verbose)] -pub(crate) struct LongTypePath { - pub(crate) path: String, -} - #[derive(Subdiagnostic)] pub(crate) enum TypeNoCopy<'a> { #[label(borrowck_ty_no_impl_copy)] diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 797dcd7b4d1df..b96df81485294 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -4,6 +4,7 @@ use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::panic; +use std::path::PathBuf; use std::thread::panicking; use rustc_data_structures::fx::FxIndexMap; @@ -301,6 +302,7 @@ pub struct DiagInner { pub is_lint: Option, + pub long_ty_path: Option, /// With `-Ztrack_diagnostics` enabled, /// we print where in rustc this error was emitted. pub(crate) emitted_at: DiagLocation, @@ -324,6 +326,7 @@ impl DiagInner { args: Default::default(), sort_span: DUMMY_SP, is_lint: None, + long_ty_path: None, emitted_at: DiagLocation::caller(), } } @@ -1293,9 +1296,37 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// `cancel`, etc. Afterwards, `drop` is the only code that will be run on /// `self`. fn take_diag(&mut self) -> DiagInner { + if let Some(path) = &self.long_ty_path { + self.note(format!( + "the full name for the type has been written to '{}'", + path.display() + )); + self.note("consider using `--verbose` to print the full type name to the console"); + } Box::into_inner(self.diag.take().unwrap()) } + /// This method allows us to access the path of the file where "long types" are written to. + /// + /// When calling `Diag::emit`, as part of that we will check if a `long_ty_path` has been set, + /// and if it has been then we add a note mentioning the file where the "long types" were + /// written to. + /// + /// When calling `tcx.short_string()` after a `Diag` is constructed, the preferred way of doing + /// so is `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that + /// keeps the existence of a "long type" anywhere in the diagnostic, so the note telling the + /// user where we wrote the file to is only printed once at most, *and* it makes it much harder + /// to forget to set it. + /// + /// If the diagnostic hasn't been created before a "short ty string" is created, then you should + /// ensure that this method is called to set it `*diag.long_ty_path() = path`. + /// + /// As a rule of thumb, if you see or add at least one `tcx.short_string()` call anywhere, in a + /// scope, `diag.long_ty_path()` should be called once somewhere close by. + pub fn long_ty_path(&mut self) -> &mut Option { + &mut self.long_ty_path + } + /// Most `emit_producing_guarantee` functions use this as a starting point. fn emit_producing_nothing(mut self) { let diag = self.take_diag(); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e4a6a0fedc5a7..920418407c0f5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -5,6 +5,7 @@ use core::ops::ControlFlow; use std::borrow::Cow; +use std::path::PathBuf; use hir::Expr; use rustc_ast::ast::Mutability; @@ -362,14 +363,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> { let mut file = None; - let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file); let mut err = struct_span_code_err!( self.dcx(), rcvr_expr.span, E0599, "cannot write into `{}`", - ty_str + self.tcx.short_string(rcvr_ty, &mut file), ); + *err.long_ty_path() = file; err.span_note( rcvr_expr.span, "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", @@ -380,11 +381,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "a writer is needed before this format string", ); }; - if let Some(file) = file { - err.note(format!("the full type name has been written to '{}'", file.display())); - err.note("consider using `--verbose` to print the full type name to the console"); - } - err } @@ -595,7 +591,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string())) } else { ( - tcx.short_ty_string(rcvr_ty, &mut ty_file), + tcx.short_string(rcvr_ty, &mut ty_file), with_forced_trimmed_paths!(rcvr_ty.to_string()), ) }; @@ -624,6 +620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, item_name, &short_ty_str, + &mut ty_file, ) { return guar; } @@ -635,6 +632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, &short_ty_str, + &mut ty_file, ) { return guar; } @@ -728,10 +726,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty_str = short_ty_str; } - if let Some(file) = ty_file { - err.note(format!("the full type name has been written to '{}'", file.display(),)); - err.note("consider using `--verbose` to print the full type name to the console"); - } if rcvr_ty.references_error() { err.downgrade_to_delayed_bug(); } @@ -1314,7 +1308,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bound_list.into_iter().map(|(_, path)| path).collect::>().join("\n"); let actual_prefix = rcvr_ty.prefix_string(self.tcx); info!("unimplemented_traits.len() == {}", unimplemented_traits.len()); - let mut long_ty_file = None; let (primary_message, label, notes) = if unimplemented_traits.len() == 1 && unimplemented_traits_only { @@ -1329,7 +1322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let OnUnimplementedNote { message, label, notes, .. } = self .err_ctxt() - .on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file); + .on_unimplemented_note(trait_ref, &obligation, &mut ty_file); (message, label, notes) }) .unwrap() @@ -1343,15 +1336,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }); err.primary_message(primary_message); - if let Some(file) = long_ty_file { - err.note(format!( - "the full name for the type has been written to '{}'", - file.display(), - )); - err.note( - "consider using `--verbose` to print the full type name to the console", - ); - } if let Some(label) = label { custom_span_label = true; err.span_label(span, label); @@ -2403,6 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, item_name: Ident, ty_str: &str, + long_ty_path: &mut Option, ) -> Result<(), ErrorGuaranteed> { if let SelfSource::MethodCall(expr) = source { for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) { @@ -2460,7 +2445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - return Err(self.dcx().emit_err(errors::MissingParenthesesInRange { + let mut err = self.dcx().create_err(errors::MissingParenthesesInRange { span, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), @@ -2469,7 +2454,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { left: range_span.shrink_to_lo(), right: range_span.shrink_to_hi(), }), - })); + }); + *err.long_ty_path() = long_ty_path.take(); + return Err(err.emit()); } } } @@ -2486,6 +2473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind: &str, item_name: Ident, ty_str: &str, + long_ty_path: &mut Option, ) -> Result<(), ErrorGuaranteed> { let found_candidate = all_traits(self.tcx) .into_iter() @@ -2526,6 +2514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name, ty_str ); + *err.long_ty_path() = long_ty_path.take(); let concrete_type = if actual.is_integral() { "i32" } else { "f32" }; match expr.kind { ExprKind::Lit(lit) => { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 35fbaa99569c9..8c1991ddb36ee 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -10,8 +10,8 @@ use rustc_hir::def::{CtorOf, DefKind}; use rustc_macros::extension; pub use rustc_type_ir::error::ExpectedFound; -use crate::ty::print::{FmtPrinter, PrettyPrinter, with_forced_trimmed_paths}; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::print::{FmtPrinter, Print, with_forced_trimmed_paths}; +use crate::ty::{self, Lift, Ty, TyCtxt}; pub type TypeError<'tcx> = rustc_type_ir::error::TypeError>; @@ -159,8 +159,8 @@ impl<'tcx> Ty<'tcx> { ty::Error(_) => "type error".into(), _ => { let width = tcx.sess.diagnostic_width(); - let length_limit = std::cmp::max(width / 4, 15); - format!("`{}`", tcx.ty_string_with_limit(self, length_limit)).into() + let length_limit = std::cmp::max(width / 4, 40); + format!("`{}`", tcx.string_with_limit(self, length_limit)).into() } } } @@ -213,10 +213,14 @@ impl<'tcx> Ty<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn ty_string_with_limit(self, ty: Ty<'tcx>, length_limit: usize) -> String { + pub fn string_with_limit<'a, T>(self, p: T, length_limit: usize) -> String + where + T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift> + Copy, + >>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, + { let mut type_limit = 50; let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { - cx.pretty_print_type(ty) + self.lift(p).expect("could not lift for printing").print(cx) }) .expect("could not write to `String`"); if regular.len() <= length_limit { @@ -231,7 +235,10 @@ impl<'tcx> TyCtxt<'tcx> { hir::def::Namespace::TypeNS, rustc_session::Limit(type_limit), ); - cx.pretty_print_type(ty).expect("could not write to `String`"); + self.lift(p) + .expect("could not lift for printing") + .print(&mut cx) + .expect("could not print type"); cx.into_buffer() }); if short.len() <= length_limit || type_limit == 0 { @@ -242,9 +249,17 @@ impl<'tcx> TyCtxt<'tcx> { short } - pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option) -> String { + /// When calling this after a `Diag` is constructed, the preferred way of doing so is + /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps + /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user + /// where we wrote the file to is only printed once. + pub fn short_string<'a, T>(self, p: T, path: &mut Option) -> String + where + T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift> + Copy + Hash, + >>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, + { let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { - cx.pretty_print_type(ty) + self.lift(p).expect("could not lift for printing").print(cx) }) .expect("could not write to `String`"); @@ -257,13 +272,13 @@ impl<'tcx> TyCtxt<'tcx> { if regular.len() <= width * 2 / 3 { return regular; } - let short = self.ty_string_with_limit(ty, length_limit); + let short = self.string_with_limit(p, length_limit); if regular == short { return regular; } // Ensure we create an unique file for the type passed in when we create a file. let mut s = DefaultHasher::new(); - ty.hash(&mut s); + p.hash(&mut s); let hash = s.finish(); *path = Some(path.take().unwrap_or_else(|| { self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 72f353f06ff52..dc2040aa5cf85 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -105,6 +105,10 @@ pub trait Printer<'tcx>: Sized { args: &[GenericArg<'tcx>], ) -> Result<(), PrintError>; + fn should_truncate(&mut self) -> bool { + false + } + // Defaults (should not be overridden): #[instrument(skip(self), level = "debug")] diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 018fcc66aeed4..6c8591dae895b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -865,7 +865,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { p!(write("{{")); if !self.tcx().sess.verbose_internals() { p!("coroutine witness"); - // FIXME(eddyb) should use `def_span`. if let Some(did) = did.as_local() { let span = self.tcx().def_span(did); p!(write( @@ -887,26 +886,30 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { p!(write("{{")); if !self.should_print_verbose() { p!(write("closure")); - // FIXME(eddyb) should use `def_span`. - if let Some(did) = did.as_local() { - if self.tcx().sess.opts.unstable_opts.span_free_formats { - p!("@", print_def_path(did.to_def_id(), args)); - } else { - let span = self.tcx().def_span(did); - let preference = if with_forced_trimmed_paths() { - FileNameDisplayPreference::Short + if self.should_truncate() { + write!(self, "@...}}")?; + return Ok(()); + } else { + if let Some(did) = did.as_local() { + if self.tcx().sess.opts.unstable_opts.span_free_formats { + p!("@", print_def_path(did.to_def_id(), args)); } else { - FileNameDisplayPreference::Remapped - }; - p!(write( - "@{}", - // This may end up in stderr diagnostics but it may also be emitted - // into MIR. Hence we use the remapped path if available - self.tcx().sess.source_map().span_to_string(span, preference) - )); + let span = self.tcx().def_span(did); + let preference = if with_forced_trimmed_paths() { + FileNameDisplayPreference::Short + } else { + FileNameDisplayPreference::Remapped + }; + p!(write( + "@{}", + // This may end up in stderr diagnostics but it may also be emitted + // into MIR. Hence we use the remapped path if available + self.tcx().sess.source_map().span_to_string(span, preference) + )); + } + } else { + p!(write("@"), print_def_path(did, args)); } - } else { - p!(write("@"), print_def_path(did, args)); } } else { p!(print_def_path(did, args)); @@ -942,7 +945,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { "coroutine from coroutine-closure should have CoroutineSource::Closure" ), } - // FIXME(eddyb) should use `def_span`. if let Some(did) = did.as_local() { if self.tcx().sess.opts.unstable_opts.span_free_formats { p!("@", print_def_path(did.to_def_id(), args)); @@ -1994,7 +1996,6 @@ pub struct FmtPrinterData<'a, 'tcx> { binder_depth: usize, printed_type_count: usize, type_length_limit: Limit, - truncated: bool, pub region_highlight_mode: RegionHighlightMode<'tcx>, @@ -2046,7 +2047,6 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> { binder_depth: 0, printed_type_count: 0, type_length_limit, - truncated: false, region_highlight_mode: RegionHighlightMode::default(), ty_infer_name_resolver: None, const_infer_name_resolver: None, @@ -2183,16 +2183,49 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { } fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> { - if self.type_length_limit.value_within_limit(self.printed_type_count) { - self.printed_type_count += 1; - self.pretty_print_type(ty) - } else { - self.truncated = true; - write!(self, "...")?; - Ok(()) + match ty.kind() { + ty::Tuple(tys) if tys.len() == 0 && self.should_truncate() => { + // Don't truncate `()`. + self.printed_type_count += 1; + self.pretty_print_type(ty) + } + ty::Adt(..) + | ty::Foreign(_) + | ty::Pat(..) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::UnsafeBinder(..) + | ty::Dynamic(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Tuple(_) + | ty::Alias(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(_) + | ty::Error(_) + if self.should_truncate() => + { + // We only truncate types that we know are likely to be much longer than 3 chars. + // There's no point in replacing `i32` or `!`. + write!(self, "...")?; + Ok(()) + } + _ => { + self.printed_type_count += 1; + self.pretty_print_type(ty) + } } } + fn should_truncate(&mut self) -> bool { + !self.type_length_limit.value_within_limit(self.printed_type_count) + } + fn print_dyn_existential( &mut self, predicates: &'tcx ty::List>, @@ -2942,7 +2975,7 @@ impl<'tcx> ty::TraitPredicate<'tcx> { } } -#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] pub struct TraitPredPrintWithBoundConstness<'tcx>( ty::TraitPredicate<'tcx>, Option, diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 053775b493789..ffdb721fb18b4 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -25,8 +25,6 @@ mir_build_borrow_of_moved_value = borrow of moved value .occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait .value_borrowed_label = value borrowed here after move .suggestion = borrow this binding in the pattern to avoid moving the value - .full_type_name = the full type name has been written to '{$path}' - .consider_verbose = consider using `--verbose` to print the full type name to the console mir_build_call_to_deprecated_safe_fn_requires_unsafe = call to deprecated safe function `{$function}` is unsafe and requires unsafe block diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 1f87bf0dbbbd6..c13db27dae856 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -801,10 +801,6 @@ pub(crate) struct BorrowOfMovedValue { pub(crate) ty: String, #[suggestion(code = "ref ", applicability = "machine-applicable")] pub(crate) suggest_borrowing: Option, - #[note(mir_build_full_type_name)] - #[note(mir_build_consider_verbose)] - pub(crate) has_path: bool, - pub(crate) path: String, } #[derive(Diagnostic)] diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index e0a1117f905c6..a237124a2113c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -796,16 +796,16 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: }); if !conflicts_ref.is_empty() { let mut path = None; - let ty = cx.tcx.short_ty_string(ty, &mut path); - sess.dcx().emit_err(BorrowOfMovedValue { + let ty = cx.tcx.short_string(ty, &mut path); + let mut err = sess.dcx().create_err(BorrowOfMovedValue { binding_span: pat.span, conflicts_ref, name: Ident::new(name, pat.span), ty, suggest_borrowing: Some(pat.span.shrink_to_lo()), - has_path: path.is_some(), - path: path.map(|p| p.display().to_string()).unwrap_or_default(), }); + *err.long_ty_path() = path; + err.emit(); } return; } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index db4a14356cc98..ac72774027cff 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -435,7 +435,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { exp_found: Option>>, terr: TypeError<'tcx>, param_env: Option>, - path: &mut Option, ) { match *cause.code() { ObligationCauseCode::Pattern { @@ -458,7 +457,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!("this is an iterator with items of type `{}`", args.type_at(0)), ); } else { - let expected_ty = self.tcx.short_ty_string(expected_ty, path); + let expected_ty = self.tcx.short_string(expected_ty, err.long_ty_path()); err.span_label(span, format!("this expression has type `{expected_ty}`")); } } @@ -1545,7 +1544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (false, Mismatch::Fixed("existential projection")) } }; - let Some(vals) = self.values_str(values, cause) else { + let Some(vals) = self.values_str(values, cause, diag.long_ty_path()) else { // Derived error. Cancel the emitter. // NOTE(eddyb) this was `.cancel()`, but `diag` // is borrowed, so we can't fully defuse it. @@ -1600,9 +1599,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return; } - let mut path = None; - if let Some((expected, found, p)) = expected_found { - path = p; + if let Some((expected, found)) = expected_found { let (expected_label, found_label, exp_found) = match exp_found { Mismatch::Variable(ef) => ( ef.expected.prefix_string(self.tcx), @@ -1878,11 +1875,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // It reads better to have the error origin as the final // thing. - self.note_error_origin(diag, cause, exp_found, terr, param_env, &mut path); - if let Some(path) = path { - diag.note(format!("the full type name has been written to '{}'", path.display())); - diag.note("consider using `--verbose` to print the full type name to the console"); - } + self.note_error_origin(diag, cause, exp_found, terr, param_env); debug!(?diag); } @@ -1891,6 +1884,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &self, trace: &TypeTrace<'tcx>, terr: TypeError<'tcx>, + path: &mut Option, ) -> Vec { let mut suggestions = Vec::new(); let span = trace.cause.span; @@ -1969,7 +1963,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) | ObligationCauseCode::BlockTailExpression(.., source)) = code && let hir::MatchSource::TryDesugar(_) = source - && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values, &trace.cause) + && let Some((expected_ty, found_ty)) = self.values_str(trace.values, &trace.cause, path) { suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { found: found_ty.content(), @@ -2048,12 +2042,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); let span = trace.cause.span; + let mut path = None; let failure_code = trace.cause.as_failure_code_diag( terr, span, - self.type_error_additional_suggestions(&trace, terr), + self.type_error_additional_suggestions(&trace, terr, &mut path), ); let mut diag = self.dcx().create_err(failure_code); + *diag.long_ty_path() = path; self.note_type_err( &mut diag, &trace.cause, @@ -2098,10 +2094,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &self, values: ValuePairs<'tcx>, cause: &ObligationCause<'tcx>, - ) -> Option<(DiagStyledString, DiagStyledString, Option)> { + file: &mut Option, + ) -> Option<(DiagStyledString, DiagStyledString)> { match values { ValuePairs::Regions(exp_found) => self.expected_found_str(exp_found), - ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found), + ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found, file), ValuePairs::Aliases(exp_found) => self.expected_found_str(exp_found), ValuePairs::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found), ValuePairs::ExistentialProjection(exp_found) => self.expected_found_str(exp_found), @@ -2111,7 +2108,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { found: exp_found.found.print_trait_sugared(), }; 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) } ret => ret, @@ -2133,9 +2130,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (None, None) }; - let (exp, fnd) = - self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2); - Some((exp, fnd, None)) + Some(self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2)) } } } @@ -2143,7 +2138,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn expected_found_str_term( &self, exp_found: ty::error::ExpectedFound>, - ) -> Option<(DiagStyledString, DiagStyledString, Option)> { + path: &mut Option, + ) -> Option<(DiagStyledString, DiagStyledString)> { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; @@ -2158,21 +2154,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let len = self.tcx.sess().diagnostic_width() + 40; let exp_s = exp.content(); let fnd_s = fnd.content(); - let mut path = None; if exp_s.len() > len { - let exp_s = self.tcx.short_ty_string(expected, &mut path); + let exp_s = self.tcx.short_string(expected, path); exp = DiagStyledString::highlighted(exp_s); } if fnd_s.len() > len { - let fnd_s = self.tcx.short_ty_string(found, &mut path); + let fnd_s = self.tcx.short_string(found, path); fnd = DiagStyledString::highlighted(fnd_s); } - (exp, fnd, path) + (exp, fnd) } _ => ( DiagStyledString::highlighted(exp_found.expected.to_string()), DiagStyledString::highlighted(exp_found.found.to_string()), - None, ), }) } @@ -2181,7 +2175,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn expected_found_str>>( &self, exp_found: ty::error::ExpectedFound, - ) -> Option<(DiagStyledString, DiagStyledString, Option)> { + ) -> Option<(DiagStyledString, DiagStyledString)> { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; @@ -2190,7 +2184,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Some(( DiagStyledString::highlighted(exp_found.expected.to_string()), DiagStyledString::highlighted(exp_found.found.to_string()), - None, )) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 68a5338123049..99b70c87ccd1c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -713,7 +713,7 @@ impl<'tcx> InferSourceKind<'tcx> { if ty.is_closure() { ("closure", closure_as_fn_str(infcx, ty), path) } else if !ty.is_ty_or_numeric_infer() { - ("normal", infcx.tcx.short_ty_string(ty, &mut path), path) + ("normal", infcx.tcx.short_string(ty, &mut path), path) } else { ("other", String::new(), path) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs deleted file mode 100644 index beae9962f7f28..0000000000000 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs +++ /dev/null @@ -1,422 +0,0 @@ -use rustc_errors::{Diag, Subdiagnostic}; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, IsSuggestable, Region, Ty}; -use rustc_span::kw; -use tracing::debug; - -use super::ObligationCauseAsDiagArg; -use crate::error_reporting::infer::{TypeErrCtxt, note_and_explain_region}; -use crate::errors::{ - FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, RefLongerThanData, - RegionOriginNote, WhereClauseSuggestions, note_and_explain, -}; -use crate::fluent_generated as fluent; -use crate::infer::{self, SubregionOrigin}; - -impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { - pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) { - match *origin { - infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { - span: trace.cause.span, - requirement: ObligationCauseAsDiagArg(trace.cause.clone()), - expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)), - } - .add_to_diag(err), - infer::Reborrow(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err) - } - infer::RelateObjectBound(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } - .add_to_diag(err); - } - infer::ReferenceOutlivesReferent(ty, span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_reference_outlives_referent, - name: &self.ty_to_string(ty), - continues: false, - } - .add_to_diag(err); - } - infer::RelateParamBound(span, ty, opt_span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_relate_param_bound, - name: &self.ty_to_string(ty), - continues: opt_span.is_some(), - } - .add_to_diag(err); - if let Some(span) = opt_span { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 } - .add_to_diag(err); - } - } - infer::RelateRegionParamBound(span, _) => { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound } - .add_to_diag(err); - } - infer::CompareImplItemObligation { span, .. } => { - RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation } - .add_to_diag(err); - } - infer::CheckAssociatedTypeBounds { ref parent, .. } => { - self.note_region_origin(err, parent); - } - infer::AscribeUserTypeProvePredicate(span) => { - RegionOriginNote::Plain { - span, - msg: fluent::infer_ascribe_user_type_prove_predicate, - } - .add_to_diag(err); - } - } - } - - pub(super) fn report_concrete_failure( - &self, - generic_param_scope: LocalDefId, - origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>, - ) -> Diag<'a> { - let mut err = match origin { - infer::Subtype(box trace) => { - let terr = TypeError::RegionsDoesNotOutlive(sup, sub); - let mut err = self.report_and_explain_type_error(trace, terr); - match (*sub, *sup) { - (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} - (ty::RePlaceholder(_), _) => { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "", - sup, - " doesn't meet the lifetime requirements", - None, - ); - } - (_, ty::RePlaceholder(_)) => { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "the required lifetime does not necessarily outlive ", - sub, - "", - None, - ); - } - _ => { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "", - sup, - "...", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "...does not necessarily outlive ", - sub, - "", - None, - ); - } - } - err - } - infer::Reborrow(span) => { - let reference_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::RefValidFor, - note_and_explain::SuffixKind::Continues, - ); - let content_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::ContentValidFor, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(OutlivesContent { - span, - notes: reference_valid.into_iter().chain(content_valid).collect(), - }) - } - infer::RelateObjectBound(span) => { - let object_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::TypeObjValidFor, - note_and_explain::SuffixKind::Empty, - ); - let pointer_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::SourcePointerValidFor, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(OutlivesBound { - span, - notes: object_valid.into_iter().chain(pointer_valid).collect(), - }) - } - infer::RelateParamBound(span, ty, opt_span) => { - let prefix = match *sub { - ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy, - _ => note_and_explain::PrefixKind::TypeOutlive, - }; - let suffix = if opt_span.is_some() { - note_and_explain::SuffixKind::ReqByBinding - } else { - note_and_explain::SuffixKind::Empty - }; - let note = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - opt_span, - prefix, - suffix, - ); - self.dcx().create_err(FulfillReqLifetime { - span, - ty: self.resolve_vars_if_possible(ty), - note, - }) - } - infer::RelateRegionParamBound(span, _) => { - let param_instantiated = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::LfParamInstantiatedWith, - note_and_explain::SuffixKind::Empty, - ); - let param_must_outlive = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::LfParamMustOutlive, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(LfBoundNotSatisfied { - span, - notes: param_instantiated.into_iter().chain(param_must_outlive).collect(), - }) - } - infer::ReferenceOutlivesReferent(ty, span) => { - let pointer_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::PointerValidFor, - note_and_explain::SuffixKind::Empty, - ); - let data_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::DataValidFor, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(RefLongerThanData { - span, - ty: self.resolve_vars_if_possible(ty), - notes: pointer_valid.into_iter().chain(data_valid).collect(), - }) - } - infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { - let mut err = self.infcx.report_extra_impl_obligation( - span, - impl_item_def_id, - trait_item_def_id, - &format!("`{sup}: {sub}`"), - ); - // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause - if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) - && generics.where_clause_span.contains(span) - { - self.suggest_copy_trait_method_bounds( - trait_item_def_id, - impl_item_def_id, - &mut err, - ); - } - err - } - infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { - let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup); - - // Don't mention the item name if it's an RPITIT, since that'll just confuse - // folks. - if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) { - let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label( - trait_item_span, - format!("definition of `{item_name}` from trait"), - ); - } - - self.suggest_copy_trait_method_bounds( - trait_item_def_id, - impl_item_def_id, - &mut err, - ); - err - } - infer::AscribeUserTypeProvePredicate(span) => { - let instantiated = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::LfInstantiatedWith, - note_and_explain::SuffixKind::Empty, - ); - let must_outlive = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::LfMustOutlive, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(LfBoundNotSatisfied { - span, - notes: instantiated.into_iter().chain(must_outlive).collect(), - }) - } - }; - if sub.is_error() || sup.is_error() { - err.downgrade_to_delayed_bug(); - } - err - } - - pub fn suggest_copy_trait_method_bounds( - &self, - trait_item_def_id: DefId, - impl_item_def_id: LocalDefId, - err: &mut Diag<'_>, - ) { - // FIXME(compiler-errors): Right now this is only being used for region - // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches, - // but right now it's not really very smart when it comes to implicit `Sized` - // predicates and bounds on the trait itself. - - let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx) - else { - return; - }; - let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else { - return; - }; - let trait_args = trait_ref - .instantiate_identity() - // Replace the explicit self type with `Self` for better suggestion rendering - .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper)) - .args; - let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id) - .rebase_onto(self.tcx, impl_def_id, trait_args); - - let Ok(trait_predicates) = - self.tcx - .explicit_predicates_of(trait_item_def_id) - .instantiate_own(self.tcx, trait_item_args) - .map(|(pred, _)| { - if pred.is_suggestable(self.tcx, false) { - Ok(pred.to_string()) - } else { - Err(()) - } - }) - .collect::, ()>>() - else { - return; - }; - - let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { - return; - }; - - let suggestion = if trait_predicates.is_empty() { - WhereClauseSuggestions::Remove { span: generics.where_clause_span } - } else { - let space = if generics.where_clause_span.is_empty() { " " } else { "" }; - WhereClauseSuggestions::CopyPredicates { - span: generics.where_clause_span, - space, - trait_predicates: trait_predicates.join(", "), - } - }; - err.subdiagnostic(suggestion); - } - - pub(super) fn report_placeholder_failure( - &self, - generic_param_scope: LocalDefId, - placeholder_origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>, - ) -> Diag<'a> { - // I can't think how to do better than this right now. -nikomatsakis - debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); - match placeholder_origin { - infer::Subtype(box ref trace) - if matches!( - &trace.cause.code().peel_derives(), - ObligationCauseCode::WhereClause(..) - | ObligationCauseCode::WhereClauseInExpr(..) - ) => - { - // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::WhereClause(_, span) - | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = - &trace.cause.code().peel_derives() - && !span.is_dummy() - { - let span = *span; - self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup) - .with_span_note(span, "the lifetime requirement is introduced here") - } else { - unreachable!( - "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." - ) - } - } - infer::Subtype(box trace) => { - let terr = TypeError::RegionsPlaceholderMismatch; - return self.report_and_explain_type_error(trace, terr); - } - _ => { - return self.report_concrete_failure( - generic_param_scope, - placeholder_origin, - sub, - sup, - ); - } - } - } -} diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 3acca47025cbd..f35a5349ecb3c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -221,7 +221,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { span: trace.cause.span, requirement: ObligationCauseAsDiagArg(trace.cause.clone()), - expected_found: self.values_str(trace.values, &trace.cause).map(|(e, f, _)| (e, f)), + expected_found: self.values_str(trace.values, &trace.cause, err.long_ty_path()), } .add_to_diag(err), infer::Reborrow(span) => { @@ -946,10 +946,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let infer::Subtype(ref sup_trace) = sup_origin && let infer::Subtype(ref sub_trace) = sub_origin - && let Some((sup_expected, sup_found, _)) = - self.values_str(sup_trace.values, &sup_trace.cause) - && let Some((sub_expected, sub_found, _)) = - self.values_str(sub_trace.values, &sup_trace.cause) + && let Some((sup_expected, sup_found)) = + self.values_str(sup_trace.values, &sup_trace.cause, err.long_ty_path()) + && let Some((sub_expected, sub_found)) = + self.values_str(sub_trace.values, &sup_trace.cause, err.long_ty_path()) && sub_expected == sup_expected && sub_found == sup_found { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index b4d294a70c071..a92f8752a97da 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -163,6 +163,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let predicate = self.resolve_vars_if_possible(obligation.predicate); let span = obligation.cause.span; + let mut file = None; debug!(?predicate, obligation.cause.code = ?obligation.cause.code()); @@ -245,7 +246,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span, E0283, "type annotations needed: cannot satisfy `{}`", - predicate, + self.tcx.short_string(predicate, &mut file), ) }; @@ -292,7 +293,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.cancel(); return e; } - err.note(format!("cannot satisfy `{predicate}`")); + let pred = self.tcx.short_string(predicate, &mut file); + err.note(format!("cannot satisfy `{pred}`")); let impl_candidates = self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap()); if impl_candidates.len() < 40 { @@ -524,6 +526,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .iter() .chain(Some(data.term.into_arg())) .find(|g| g.has_non_region_infer()); + let predicate = self.tcx.short_string(predicate, &mut file); if let Some(arg) = arg { self.emit_inference_failure_err( obligation.cause.body_id, @@ -539,8 +542,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.dcx(), span, E0284, - "type annotations needed: cannot satisfy `{}`", - predicate, + "type annotations needed: cannot satisfy `{predicate}`", ) .with_span_label(span, format!("cannot satisfy `{predicate}`")) } @@ -565,12 +567,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err } else { // If we can't find a generic parameter, just print a generic error + let predicate = self.tcx.short_string(predicate, &mut file); struct_span_code_err!( self.dcx(), span, E0284, - "type annotations needed: cannot satisfy `{}`", - predicate, + "type annotations needed: cannot satisfy `{predicate}`", ) .with_span_label(span, format!("cannot satisfy `{predicate}`")) } @@ -590,6 +592,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some(e) = self.tainted_by_errors() { return e; } + let alias = self.tcx.short_string(alias, &mut file); struct_span_code_err!( self.dcx(), span, @@ -603,16 +606,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some(e) = self.tainted_by_errors() { return e; } + let predicate = self.tcx.short_string(predicate, &mut file); struct_span_code_err!( self.dcx(), span, E0284, - "type annotations needed: cannot satisfy `{}`", - predicate, + "type annotations needed: cannot satisfy `{predicate}`", ) .with_span_label(span, format!("cannot satisfy `{predicate}`")) } }; + *err.long_ty_path() = file; self.note_obligation_cause(&mut err, obligation); err.emit() } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 6416c539f2616..d0a193e8bd524 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1,5 +1,6 @@ use core::ops::ControlFlow; use std::borrow::Cow; +use std::path::PathBuf; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::FxHashMap; @@ -9,7 +10,6 @@ use rustc_errors::{ Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions, pluralize, struct_span_code_err, }; -use rustc_hir::def::Namespace; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, LangItem, Node}; @@ -20,8 +20,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{ - FmtPrinter, Print, PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _, - PrintTraitRefExt as _, with_forced_trimmed_paths, + PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _, PrintTraitRefExt as _, + with_forced_trimmed_paths, }; use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast}; use rustc_middle::{bug, span_bug}; @@ -60,6 +60,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> ErrorGuaranteed { let tcx = self.tcx; let mut span = obligation.cause.span; + let mut long_ty_file = None; let mut err = match *error { SelectionError::Unimplemented => { @@ -169,11 +170,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Err(guar) = self.fn_arg_obligation(&obligation) { return guar; } - let mut file = None; let (post_message, pre_message, type_def) = self .get_parent_trait_ref(obligation.cause.code()) .map(|(t, s)| { - let t = self.tcx.short_ty_string(t, &mut file); + let t = self.tcx.short_string(t, &mut long_ty_file); ( format!(" in `{t}`"), format!("within `{t}`, "), @@ -181,12 +181,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) }) .unwrap_or_default(); - let file_note = file.as_ref().map(|file| format!( - "the full trait has been written to '{}'", - file.display(), - )); - - let mut long_ty_file = None; let OnUnimplementedNote { message, @@ -223,6 +217,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { None, append_const_msg, post_message, + &mut long_ty_file, ); let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::TransmuteTrait) @@ -251,14 +246,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); + *err.long_ty_path() = long_ty_file; - if let Some(long_ty_file) = long_ty_file { - err.note(format!( - "the full name for the type has been written to '{}'", - long_ty_file.display(), - )); - err.note("consider using `--verbose` to print the full type name to the console"); - } let mut suggested = false; if is_try_conversion { suggested = self.try_conversion_context(&obligation, main_trait_predicate, &mut err); @@ -309,7 +298,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return err.emit(); } - file_note.map(|note| err.note(note)); if let Some(s) = label { // If it has a custom `#[rustc_on_unimplemented]` // error message, let's display it as the label! @@ -762,14 +750,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_ref: predicate.trait_ref, polarity: ty::PredicatePolarity::Positive, }); + let mut file = None; let err_msg = self.get_standard_error_message( trait_ref, None, Some(predicate.constness()), None, String::new(), + &mut file, ); let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); + *diag.long_ty_path() = file; if !self.predicate_may_hold(&Obligation::new( self.tcx, ObligationCause::dummy(), @@ -1381,6 +1372,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => (None, error.err), }; + let mut file = None; let (msg, span, closure_span) = values .and_then(|(predicate, normalized_term, expected_term)| { self.maybe_detailed_projection_msg( @@ -1388,24 +1380,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { predicate, normalized_term, expected_term, + &mut file, ) }) .unwrap_or_else(|| { - let mut cx = FmtPrinter::new_with_limit( - self.tcx, - Namespace::TypeNS, - rustc_session::Limit(10), - ); ( - with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", { - self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap(); - cx.into_buffer() - })), + with_forced_trimmed_paths!(format!( + "type mismatch resolving `{}`", + self.tcx + .short_string(self.resolve_vars_if_possible(predicate), &mut file), + )), obligation.cause.span, None, ) }); let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}"); + *diag.long_ty_path() = file; if let Some(span) = closure_span { // Mark the closure decl so that it is seen even if we are pointing at the return // type or expression. @@ -1471,15 +1461,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty.span, with_forced_trimmed_paths!(Cow::from(format!( "type mismatch resolving `{}`", - { - let mut cx = FmtPrinter::new_with_limit( - self.tcx, - Namespace::TypeNS, - rustc_session::Limit(5), - ); - self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap(); - cx.into_buffer() - } + self.tcx.short_string( + self.resolve_vars_if_possible(predicate), + diag.long_ty_path() + ), ))), true, )), @@ -1512,6 +1497,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { projection_term: ty::AliasTerm<'tcx>, normalized_ty: ty::Term<'tcx>, expected_ty: ty::Term<'tcx>, + file: &mut Option, ) -> Option<(String, Span, Option)> { let trait_def_id = projection_term.trait_def_id(self.tcx); let self_ty = projection_term.self_ty(); @@ -1552,7 +1538,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), - _ => self_ty.to_string(), + _ => self.tcx.short_string(self_ty, file), }; Some((format!( "expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \ @@ -1984,8 +1970,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { StringPart::normal(" implemented for `"), ]); if types_content.0 == types_content.1 { - let ty = - self.tcx.short_ty_string(obligation_trait_ref.self_ty(), &mut None); + let ty = self + .tcx + .short_string(obligation_trait_ref.self_ty(), err.long_ty_path()); msg.push(StringPart::normal(ty)); } else { msg.extend(types.0.0); @@ -2342,7 +2329,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // First, attempt to add note to this error with an async-await-specific // message, and fall back to regular note otherwise. if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { - let mut long_ty_file = None; self.note_obligation_cause_code( obligation.cause.body_id, err, @@ -2351,15 +2337,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation.cause.code(), &mut vec![], &mut Default::default(), - &mut long_ty_file, ); - if let Some(file) = long_ty_file { - err.note(format!( - "the full name for the type has been written to '{}'", - file.display(), - )); - err.note("consider using `--verbose` to print the full type name to the console"); - } self.suggest_unsized_bound_if_applicable(err, obligation); if let Some(span) = err.span.primary_span() && let Some(mut diag) = @@ -2403,6 +2381,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { predicate_constness: Option, append_const_msg: Option, post_message: String, + long_ty_file: &mut Option, ) -> String { message .and_then(|cannot_do_this| { @@ -2426,7 +2405,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .unwrap_or_else(|| { format!( "the trait bound `{}` is not satisfied{post_message}", - trait_predicate.print_with_bound_constness(predicate_constness) + self.tcx.short_string( + trait_predicate.print_with_bound_constness(predicate_constness), + long_ty_file, + ), ) }) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 8111983c53982..d1bd23bf8266c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -306,7 +306,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) = code { - let mut long_ty_file = None; self.note_obligation_cause_code( error.obligation.cause.body_id, &mut diag, @@ -315,17 +314,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { code, &mut vec![], &mut Default::default(), - &mut long_ty_file, ); - if let Some(file) = long_ty_file { - diag.note(format!( - "the full name for the type has been written to '{}'", - file.display(), - )); - diag.note( - "consider using `--verbose` to print the full type name to the console", - ); - } } diag.emit() } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 3d79b0acf83a9..518323f6526a6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -932,7 +932,7 @@ impl<'tcx> OnUnimplementedFormatString { let value = match param.kind { GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { if let Some(ty) = trait_ref.args[param.index as usize].as_type() { - tcx.short_ty_string(ty, long_ty_file) + tcx.short_string(ty, long_ty_file) } else { trait_ref.args[param.index as usize].to_string() } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs index d82acc4e0543f..fad03b5e9bf5a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs @@ -141,7 +141,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation.cause.span, suggest_increasing_limit, |err| { - let mut long_ty_file = None; self.note_obligation_cause_code( obligation.cause.body_id, err, @@ -150,17 +149,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation.cause.code(), &mut vec![], &mut Default::default(), - &mut long_ty_file, ); - if let Some(file) = long_ty_file { - err.note(format!( - "the full name for the type has been written to '{}'", - file.display(), - )); - err.note( - "consider using `--verbose` to print the full type name to the console", - ); - } }, ); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ab25bef4120ee..24ca7bb7fc207 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3,7 +3,6 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; -use std::path::PathBuf; use itertools::{EitherOrBoth, Itertools}; use rustc_abi::ExternAbi; @@ -1297,30 +1296,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Because of this, we modify the error to refer to the original obligation and // return early in the caller. - let msg = format!("the trait bound `{old_pred}` is not satisfied"); + let msg = format!( + "the trait bound `{}` is not satisfied", + self.tcx.short_string(old_pred, err.long_ty_path()), + ); + let self_ty_str = + self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); if has_custom_message { err.note(msg); } else { err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; } - let mut file = None; err.span_label( span, format!( - "the trait `{}` is not implemented for `{}`", - old_pred.print_modifiers_and_trait_path(), - self.tcx.short_ty_string(old_pred.self_ty().skip_binder(), &mut file), + "the trait `{}` is not implemented for `{self_ty_str}`", + old_pred.print_modifiers_and_trait_path() ), ); - if let Some(file) = file { - err.note(format!( - "the full type name has been written to '{}'", - file.display() - )); - err.note( - "consider using `--verbose` to print full type name to the console", - ); - } if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { err.span_suggestions( @@ -2689,7 +2682,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Add a note for the item obligation that remains - normally a note pointing to the // bound that introduced the obligation (e.g. `T: Send`). debug!(?next_code); - let mut long_ty_file = None; self.note_obligation_cause_code( obligation.cause.body_id, err, @@ -2698,7 +2690,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { next_code.unwrap(), &mut Vec::new(), &mut Default::default(), - &mut long_ty_file, ); } @@ -2711,7 +2702,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { cause_code: &ObligationCauseCode<'tcx>, obligated_types: &mut Vec>, seen_requirements: &mut FxHashSet, - long_ty_file: &mut Option, ) where T: Upcast, ty::Predicate<'tcx>>, { @@ -2965,9 +2955,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ObligationCauseCode::Coercion { source, target } => { let source = - tcx.short_ty_string(self.resolve_vars_if_possible(source), long_ty_file); + tcx.short_string(self.resolve_vars_if_possible(source), err.long_ty_path()); let target = - tcx.short_ty_string(self.resolve_vars_if_possible(target), long_ty_file); + tcx.short_string(self.resolve_vars_if_possible(target), err.long_ty_path()); err.note(with_forced_trimmed_paths!(format!( "required for the cast from `{source}` to `{target}`", ))); @@ -3252,7 +3242,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; if !is_upvar_tys_infer_tuple { - let ty_str = tcx.short_ty_string(ty, long_ty_file); + let ty_str = tcx.short_string(ty, err.long_ty_path()); let msg = format!("required because it appears within the type `{ty_str}`"); match ty.kind() { ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) { @@ -3330,7 +3320,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &data.parent_code, obligated_types, seen_requirements, - long_ty_file, ) }); } else { @@ -3343,7 +3332,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { cause_code.peel_derives(), obligated_types, seen_requirements, - long_ty_file, ) }); } @@ -3353,7 +3341,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.resolve_vars_if_possible(data.derived.parent_trait_pred); let parent_def_id = parent_trait_pred.def_id(); let self_ty_str = - tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file); + tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path()); let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string(); let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`"); let mut is_auto_trait = false; @@ -3449,8 +3437,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { count, pluralize!(count) )); - let self_ty = tcx - .short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file); + let self_ty = tcx.short_string( + parent_trait_pred.skip_binder().self_ty(), + err.long_ty_path(), + ); err.note(format!( "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() @@ -3466,7 +3456,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &data.parent_code, obligated_types, seen_requirements, - long_ty_file, ) }); } @@ -3505,7 +3494,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &data.derived.parent_code, obligated_types, seen_requirements, - long_ty_file, ) }); } @@ -3519,7 +3507,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &data.parent_code, obligated_types, seen_requirements, - long_ty_file, ) }); } @@ -3536,7 +3523,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &data.parent_code, obligated_types, seen_requirements, - long_ty_file, ) }); } @@ -3551,7 +3537,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { nested, obligated_types, seen_requirements, - long_ty_file, ) }); let mut multispan = MultiSpan::from(span); @@ -3582,7 +3567,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { parent_code, obligated_types, seen_requirements, - long_ty_file, ) }); } @@ -3622,7 +3606,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ObligationCauseCode::OpaqueReturnType(expr_info) => { let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { - let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file); + let expr_ty = tcx.short_string(expr_ty, err.long_ty_path()); let expr = tcx.hir().expect_expr(hir_id); (expr_ty, expr) } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() @@ -3637,7 +3621,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder() && self.can_eq(param_env, pred.self_ty(), expr_ty) { - let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file); + let expr_ty = tcx.short_string(expr_ty, err.long_ty_path()); (expr_ty, expr) } else { return; @@ -5231,7 +5215,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>( format!( "{pre_message}the trait `{}` is not implemented for{desc} `{}`", trait_predicate.print_modifiers_and_trait_path(), - tcx.short_ty_string(trait_predicate.self_ty().skip_binder(), &mut None), + tcx.short_string(trait_predicate.self_ty().skip_binder(), &mut None), ) } else { // "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is diff --git a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr index 0c220a13876b8..b682bdac0341d 100644 --- a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr +++ b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr @@ -29,7 +29,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:14:27 | LL | let _ = type_ascribe!(Box::new( { |x| (x as u8) }), Box _>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:14:39}>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box u8>`, found `Box<{closure@...}>` | = note: expected struct `Box u8>` found struct `Box<{closure@$DIR/coerce-expect-unsized-ascribed.rs:14:39: 14:42}>` @@ -85,7 +85,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:22:27 | LL | let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _); - | ^^^^^^^^^^^^^^^^^^ expected `&dyn Fn(i32) -> u8`, found `&{closure@coerce-expect-unsized-ascribed.rs:22:30}` + | ^^^^^^^^^^^^^^^^^^ expected `&dyn Fn(i32) -> u8`, found `&{closure@...}` | = note: expected reference `&dyn Fn(i32) -> u8` found reference `&{closure@$DIR/coerce-expect-unsized-ascribed.rs:22:30: 22:33}` @@ -123,7 +123,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:27:27 | LL | let _ = type_ascribe!(Box::new(|x| (x as u8)), Box _>); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Box u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:27:36}>` + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Box u8>`, found `Box<{closure@...}>` | = note: expected struct `Box u8>` found struct `Box<{closure@$DIR/coerce-expect-unsized-ascribed.rs:27:36: 27:39}>` diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr index 7446b1a543e70..93555b336a66f 100644 --- a/tests/ui/diagnostic-width/E0271.ascii.stderr +++ b/tests/ui/diagnostic-width/E0271.ascii.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving `>, ...>>, ...>>, ...> as Future>::Error == Foo` +error[E0271]: type mismatch resolving ` as Future>::Error == Foo` --> $DIR/E0271.rs:20:5 | LL | / Box::new( @@ -7,14 +7,16 @@ LL | | Err::<(), _>( LL | | Ok::<_, ()>( ... | LL | | ) - | |_____^ type mismatch resolving `, ...>>, ...> as Future>::Error == Foo` + | |_____^ type mismatch resolving ` as Future>::Error == Foo` | note: expected this to be `Foo` --> $DIR/E0271.rs:10:18 | LL | type Error = E; | ^ - = note: required for the cast from `Box>, ()>>, ()>>, ()>>` to `Box<(dyn Future + 'static)>` + = note: required for the cast from `Box>` to `Box<...>` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.ascii/E0271.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index 061ba45c21980..2faf09d46c6ea 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode -//@[ascii] compile-flags: --diagnostic-width=40 -//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 +//@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes //@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Future { type Error; diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr index 72df2a381a422..1e9acf603b2bd 100644 --- a/tests/ui/diagnostic-width/E0271.unicode.stderr +++ b/tests/ui/diagnostic-width/E0271.unicode.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving `>, ...>>, ...>>, ...> as Future>::Error == Foo` +error[E0271]: type mismatch resolving ` as Future>::Error == Foo` ╭▸ $DIR/E0271.rs:20:5 │ LL │ ┏ Box::new( @@ -7,14 +7,16 @@ LL │ ┃ Err::<(), _>( LL │ ┃ Ok::<_, ()>( ‡ ┃ LL │ ┃ ) - │ ┗━━━━━┛ type mismatch resolving `, ...>>, ...> as Future>::Error == Foo` + │ ┗━━━━━┛ type mismatch resolving ` as Future>::Error == Foo` ╰╴ note: expected this to be `Foo` ╭▸ $DIR/E0271.rs:10:18 │ LL │ type Error = E; │ ━ - ╰ note: required for the cast from `Box>, ()>>, ()>>, ()>>` to `Box<(dyn Future + 'static)>` + ├ note: required for the cast from `Box>` to `Box<...>` + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.unicode/E0271.long-type-hash.txt' + ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr index 3053e37a87a79..83da558618870 100644 --- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr +++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr @@ -16,11 +16,11 @@ LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok... LL | | Ok("") LL | | )))))))))))))))))))))))))))))) LL | | )))))))))))))))))))))))))))))); - | |__________________________________^ expected `Atype, ...>`, found `Result, ...>` + | |__________________________________^ expected `Atype, i32>, i32>`, found `Result, _>, _>` | - = note: expected struct `Atype, ...>` - found enum `Result, ...>` - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: expected struct `Atype, i32>` + found enum `Result, _>` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types @@ -32,11 +32,11 @@ 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 `Option>`, found `Result, ...>` + | |____________________________^ expected `Option>, _>>`, found `Result, _>, _>` | - = note: expected enum `Option>` - found enum `Result, ...>` - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: expected enum `Option, _>>` + found enum `Result, _>` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types @@ -50,13 +50,13 @@ LL | | Atype< ... | LL | | i32 LL | | > = (); - | | - ^^ expected `Atype, ...>`, found `()` + | | - ^^ expected `Atype, i32>, i32>`, found `()` | |_____| | expected due to this | - = note: expected struct `Atype, ...>` + = note: expected struct `Atype, i32>` found unit type `()` - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types @@ -70,11 +70,11 @@ 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 `Result, ...>` + | |____________________________^ expected `()`, found `Result, _>, _>` | = note: expected unit type `()` - found enum `Result, ...>` - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + found enum `Result, _>` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr index 50b386325b938..54abf576dbd07 100644 --- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr +++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr @@ -16,11 +16,11 @@ LL │ ┃ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O… LL │ ┃ Ok("") LL │ ┃ )))))))))))))))))))))))))))))) LL │ ┃ )))))))))))))))))))))))))))))); - │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype, ...>`, found `Result, ...>` + │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype, i32>, i32>`, found `Result, _>, _>` │ - ├ note: expected struct `Atype, ...>` - │ found enum `Result, ...>` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: expected struct `Atype, i32>` + │ found enum `Result, _>` + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types @@ -32,11 +32,11 @@ LL │ ┃ Ok(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 `Option>`, found `Result, ...>` + │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option>, _>>`, found `Result, _>, _>` │ - ├ note: expected enum `Option>` - │ found enum `Result, ...>` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: expected enum `Option, _>>` + │ found enum `Result, _>` + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types @@ -50,13 +50,13 @@ LL │ │ Atype< ‡ │ LL │ │ i32 LL │ │ > = (); - │ │ │ ━━ expected `Atype, ...>`, found `()` + │ │ │ ━━ expected `Atype, i32>, i32>`, found `()` │ └─────┤ │ expected due to this │ - ├ note: expected struct `Atype, ...>` + ├ note: expected struct `Atype, i32>` │ found unit type `()` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error[E0308]: mismatched types @@ -70,11 +70,11 @@ LL │ ┃ Ok(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 `Result, ...>` + │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result, _>, _>` │ ├ note: expected unit type `()` - │ found enum `Result, ...>` - ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + │ found enum `Result, _>` + ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' ╰ note: consider using `--verbose` to print the full type name to the console error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs new file mode 100644 index 0000000000000..9b3bd8bb72896 --- /dev/null +++ b/tests/ui/diagnostic-width/long-e0277.rs @@ -0,0 +1,15 @@ +//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +// The regex below normalizes the long type file name to make it suitable for compare-modes. +//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" +type A = (i32, i32, i32, i32); +type B = (A, A, A, A); +type C = (B, B, B, B); +type D = (C, C, C, C); + +trait Trait {} + +fn require_trait() {} + +fn main() { + require_trait::(); //~ ERROR the trait bound `(... +} diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr new file mode 100644 index 0000000000000..a57270df7e252 --- /dev/null +++ b/tests/ui/diagnostic-width/long-e0277.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied + --> $DIR/long-e0277.rs:14:21 + | +LL | require_trait::(); + | ^ unsatisfied trait bound + | + = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)` +help: this trait has no implementations, consider adding one + --> $DIR/long-e0277.rs:9:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ +note: required by a bound in `require_trait` + --> $DIR/long-e0277.rs:11:21 + | +LL | fn require_trait() {} + | ^^^^^ required by this bound in `require_trait` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: consider using `--verbose` to print the full type name to the console + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr index 889a2b3666dd0..254542c7b3908 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr +++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr @@ -2,13 +2,13 @@ error[E0382]: use of moved value: `x` --> $DIR/non-copy-type-moved.rs:16:14 | LL | fn foo(x: D) { - | - move occurs because `x` has type `((..., ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait + | - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait LL | let _a = x; | - value moved here LL | let _b = x; | ^ value used here after move | - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console help: consider cloning the value if the performance cost is acceptable | diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs index 4caa94244250c..c8845af318357 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs @@ -12,7 +12,7 @@ fn foo(x: D) { //~^ NOTE this expression has type `((..., //~| NOTE expected `((..., //~| NOTE expected tuple - //~| NOTE the full type name has been written to + //~| NOTE the full name for the type has been written to //~| NOTE consider using `--verbose` to print the full type name to the console } diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr index 346b112019fa8..a95e17091489e 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr @@ -8,7 +8,7 @@ LL | let () = x; | = note: expected tuple `((..., ..., ..., ...), ..., ..., ...)` found unit type `()` - = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' + = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr index 67417a5e525cf..be2eca3e61ad9 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr @@ -11,7 +11,7 @@ LL | | ), LL | | ) { | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type LL | f - | ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&...)))`, found `&dyn Fn(u32)` + | ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...))))`, found `&dyn Fn(u32)` | = note: expected reference `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` found reference `&dyn Fn(u32)` diff --git a/tests/ui/suggestions/box-future-wrong-output.stderr b/tests/ui/suggestions/box-future-wrong-output.stderr index 6a232c3444d93..bac26ae8fb5dd 100644 --- a/tests/ui/suggestions/box-future-wrong-output.stderr +++ b/tests/ui/suggestions/box-future-wrong-output.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/box-future-wrong-output.rs:20:39 | LL | let _: BoxFuture<'static, bool> = async {}.boxed(); - | ------------------------ ^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | ------------------------ ^^^^^^^^^^^^^^^^ expected `Pin>`, found `Pin + Send>>` | | | expected due to this | diff --git a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 42bc094859a97..61a1d30d31d4a 100644 --- a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -32,7 +32,7 @@ error[E0308]: mismatched types LL | fn baz + Send + 'static>(x: F) -> BoxFuture<'static, i32> { | - found this type parameter LL | Pin::new(x) - | -------- ^ expected `Box + Send>`, found type parameter `F` + | -------- ^ expected `Box + Send>`, found type parameter `F` | | | arguments to this function are incorrect | help: use `Box::pin` to pin and box this expression: `Box::pin` diff --git a/tests/ui/suggestions/issue-107860.stderr b/tests/ui/suggestions/issue-107860.stderr index 4be495da46b1f..2bfd219398141 100644 --- a/tests/ui/suggestions/issue-107860.stderr +++ b/tests/ui/suggestions/issue-107860.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-107860.rs:3:36 | LL | async fn str(T: &str) -> &str { &str } - | ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}` + | ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<_>}` | = note: expected reference `&str` found reference `&for<'a> fn(&'a str) -> impl Future {str::<_>}` diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr index 8bfda71bac1fb..5299236026d7e 100644 --- a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr +++ b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr @@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving ` as Pointee>:: --> $DIR/ice-with-dyn-pointee-errors.rs:9:33 | LL | unknown_sized_object_ptr_in(x) - | --------------------------- ^ expected `()`, found `DynMetadata>` + | --------------------------- ^ expected `()`, found `DynMetadata>` | | | required by a bound introduced by this call | diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr index af941e69c5f84..2f9fdf151f08c 100644 --- a/tests/ui/traits/object/pretty.stderr +++ b/tests/ui/traits/object/pretty.stderr @@ -110,7 +110,7 @@ error[E0308]: mismatched types --> $DIR/pretty.rs:36:79 | LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x } - | - ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = ...>` + | - ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = &u8>` | | | help: try adding a return type: `-> &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>` | @@ -132,7 +132,7 @@ error[E0308]: mismatched types --> $DIR/pretty.rs:38:73 | LL | fn dyn_any_different_binders(x: &dyn AnyDifferentBinders) { x } - | - ^ expected `()`, found `&dyn AnyDifferentBinders` + | - ^ expected `()`, found `&dyn AnyDifferentBinders` | | | help: try adding a return type: `-> &dyn AnyDifferentBinders` | diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr index 5722f4006ffd9..2705d7c501ec6 100644 --- a/tests/ui/traits/on_unimplemented_long_types.stderr +++ b/tests/ui/traits/on_unimplemented_long_types.stderr @@ -13,8 +13,6 @@ LL | | ))))))))))), LL | | ))))))))))) | |_______________- return type was inferred to be `Option>>` here | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' - = note: consider using `--verbose` to print the full type name to the console = help: the trait `std::fmt::Display` is not implemented for `Option>>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' diff --git a/tests/ui/typeck/issue-107775.stderr b/tests/ui/typeck/issue-107775.stderr index dad7e1581e79a..1be2689746941 100644 --- a/tests/ui/typeck/issue-107775.stderr +++ b/tests/ui/typeck/issue-107775.stderr @@ -6,7 +6,7 @@ LL | map.insert(1, Struct::do_something); | | | ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin + Send>> {::do_something::<'_>}>` LL | Self { map } - | ^^^ expected `HashMap Pin<...>>`, found `HashMap<{integer}, ...>` + | ^^^ expected `HashMap Pin>>`, found `HashMap<{integer}, ...>` | = note: expected struct `HashMap Pin + Send + 'static)>>>` found struct `HashMap<{integer}, fn(_) -> Pin + Send>> {::do_something::<'_>}>` diff --git a/tests/ui/typeck/return_type_containing_closure.rs b/tests/ui/typeck/return_type_containing_closure.rs index b81cac0a58ab9..a9bb89bae2d6a 100644 --- a/tests/ui/typeck/return_type_containing_closure.rs +++ b/tests/ui/typeck/return_type_containing_closure.rs @@ -2,7 +2,7 @@ fn foo() { //~ HELP try adding a return type vec!['a'].iter().map(|c| c) //~^ ERROR mismatched types [E0308] - //~| NOTE expected `()`, found `Map, ...>` + //~| NOTE expected `()`, found `Map, {closure@...}>` //~| NOTE expected unit type `()` //~| HELP consider using a semicolon here } diff --git a/tests/ui/typeck/return_type_containing_closure.stderr b/tests/ui/typeck/return_type_containing_closure.stderr index 3f14650a82cce..a60bf79a57b8a 100644 --- a/tests/ui/typeck/return_type_containing_closure.stderr +++ b/tests/ui/typeck/return_type_containing_closure.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/return_type_containing_closure.rs:3:5 | LL | vec!['a'].iter().map(|c| c) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Map, ...>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Map, {closure@...}>` | = note: expected unit type `()` found struct `Map, {closure@$DIR/return_type_containing_closure.rs:3:26: 3:29}>`