diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b9f1a4220b80f..893da93085533 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -418,10 +418,10 @@ fn compute_hir_hash( pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { let sess = tcx.sess; // Queries that borrow `resolver_for_lowering`. - tcx.ensure_with_value().output_filenames(()); - tcx.ensure_with_value().early_lint_checks(()); - tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE); - tcx.ensure_with_value().get_lang_items(()); + tcx.ensure_done().output_filenames(()); + tcx.ensure_done().early_lint_checks(()); + tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); + tcx.ensure_done().get_lang_items(()); let (mut resolver, krate) = tcx.resolver_for_lowering().steal(); let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); 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 0118b72962de3..0cbbd54674230 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_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 27adf6318e227..a52b18573b152 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -692,7 +692,7 @@ pub(crate) fn run_aot( if tcx.dep_graph.is_fully_enabled() { for cgu in cgus { - tcx.ensure().codegen_unit(cgu.name()); + tcx.ensure_ok().codegen_unit(cgu.name()); } } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 6e0333cf3cef6..df945920ee8df 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -634,7 +634,7 @@ pub fn codegen_crate( // unnecessarily. if tcx.dep_graph.is_fully_enabled() { for cgu in codegen_units { - tcx.ensure().codegen_unit(cgu.name()); + tcx.ensure_ok().codegen_unit(cgu.name()); } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index c9d38a0f93253..d489926148795 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -317,7 +317,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) if let Some(pp_mode) = sess.opts.pretty { if pp_mode.needs_ast_map() { create_and_enter_global_ctxt(compiler, krate, |tcx| { - tcx.ensure().early_lint_checks(()); + tcx.ensure_ok().early_lint_checks(()); pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx }); passes::write_dep_info(tcx); }); @@ -365,7 +365,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) return early_exit(); } - tcx.ensure().analysis(()); + tcx.ensure_ok().analysis(()); if callbacks.after_analysis(compiler, tcx) == Compilation::Stop { return early_exit(); diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 699742aa0ea1a..9ace486fa56f7 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -222,7 +222,7 @@ impl<'tcx> PrintExtra<'tcx> { pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { if ppm.needs_analysis() { - ex.tcx().ensure().analysis(()); + ex.tcx().ensure_ok().analysis(()); } let (src, src_name) = get_source(sess); 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_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 40049f96de4a1..6c534d58a7da8 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -778,13 +778,13 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { match tcx.def_kind(def_id) { DefKind::Static { .. } => { - tcx.ensure().typeck(def_id); + tcx.ensure_ok().typeck(def_id); maybe_check_static_with_link_section(tcx, def_id); check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); } DefKind::Const => { - tcx.ensure().typeck(def_id); + tcx.ensure_ok().typeck(def_id); } DefKind::Enum => { check_enum(tcx, def_id); @@ -804,7 +804,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { DefKind::Impl { of_trait } => { if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { if tcx - .ensure() + .ensure_ok() .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id) .is_ok() { @@ -1042,7 +1042,7 @@ fn check_impl_items_against_trait<'tcx>( continue; }; - let res = tcx.ensure().compare_impl_item(impl_item.expect_local()); + let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local()); if res.is_ok() { match ty_impl_item.kind { @@ -1488,7 +1488,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { for v in def.variants() { if let ty::VariantDiscr::Explicit(discr_def_id) = v.discr { - tcx.ensure().typeck(discr_def_id.expect_local()); + tcx.ensure_ok().typeck(discr_def_id.expect_local()); } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 3bff5fe02c033..a91d72e922518 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2034,7 +2034,7 @@ pub(super) fn check_type_bounds<'tcx>( ) -> Result<(), ErrorGuaranteed> { // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure().coherent_trait(impl_trait_ref.def_id)?; + tcx.ensure_ok().coherent_trait(impl_trait_ref.def_id)?; let param_env = tcx.param_env(impl_ty.def_id); debug!(?param_env); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c9837ca3716c6..79e2d764ac598 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1046,7 +1046,7 @@ fn check_associated_item( // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure() + tcx.ensure_ok() .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?; let self_ty = match item.container { @@ -1354,7 +1354,7 @@ fn check_impl<'tcx>( let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity(); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure().coherent_trait(trait_ref.def_id)?; + tcx.ensure_ok().coherent_trait(trait_ref.def_id)?; let trait_span = hir_trait_ref.path.span; let trait_ref = wfcx.normalize( trait_span, @@ -2268,11 +2268,13 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_module_items(module); let res = items - .par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)) - .and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) - .and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) - .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) - .and(items.par_opaques(|item| tcx.ensure().check_well_formed(item))); + .par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)) + .and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))) + .and(items.par_trait_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))) + .and( + items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)), + ) + .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item))); if module == LocalModDefId::CRATE_DEF_ID { super::entry::check_for_entry_fn(tcx); } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 30f51fe17246f..3511dbc625295 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -192,7 +192,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E // errors; other parts of the code may demand it for the info of // course. let span = tcx.def_span(impl_did); - tcx.at(span).ensure().coerce_unsized_info(impl_did) + tcx.at(span).ensure_ok().coerce_unsized_info(impl_did) } fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index b9ef166fc3f10..1bc60087ab5ee 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -151,7 +151,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) }; // Trigger building the specialization graph for the trait. This will detect and report any // overlap errors. - let mut res = tcx.ensure().specialization_graph_of(def_id); + let mut res = tcx.ensure_ok().specialization_graph_of(def_id); for &impl_def_id in impls { let trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); @@ -162,7 +162,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> .and(check_impl(tcx, impl_def_id, trait_ref, trait_def)) .and(check_object_overlap(tcx, impl_def_id, trait_ref)) .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)) - .and(tcx.ensure().orphan_check_impl(impl_def_id)) + .and(tcx.ensure_ok().orphan_check_impl(impl_def_id)) .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 226370fccadde..ce7319f656190 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -292,16 +292,16 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} hir::GenericParamKind::Type { default: Some(_), .. } => { - self.tcx.ensure().type_of(param.def_id); + self.tcx.ensure_ok().type_of(param.def_id); } hir::GenericParamKind::Type { .. } => {} hir::GenericParamKind::Const { default, .. } => { - self.tcx.ensure().type_of(param.def_id); + self.tcx.ensure_ok().type_of(param.def_id); if let Some(default) = default { // need to store default and type of default - self.tcx.ensure().const_param_default(param.def_id); + self.tcx.ensure_ok().const_param_default(param.def_id); if let hir::ConstArgKind::Anon(ac) = default.kind { - self.tcx.ensure().type_of(ac.def_id); + self.tcx.ensure_ok().type_of(ac.def_id); } } } @@ -312,8 +312,8 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { if let hir::ExprKind::Closure(closure) = expr.kind { - self.tcx.ensure().generics_of(closure.def_id); - self.tcx.ensure().codegen_fn_attrs(closure.def_id); + self.tcx.ensure_ok().generics_of(closure.def_id); + self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id); // We do not call `type_of` for closures here as that // depends on typecheck and would therefore hide // any further errors in case one typeck fails. @@ -325,15 +325,15 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { /// `check_item_type` ensures that it's called instead. fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { let def_id = opaque.def_id; - self.tcx.ensure().generics_of(def_id); - self.tcx.ensure().predicates_of(def_id); - self.tcx.ensure().explicit_item_bounds(def_id); - self.tcx.ensure().explicit_item_self_bounds(def_id); - self.tcx.ensure().item_bounds(def_id); - self.tcx.ensure().item_self_bounds(def_id); + self.tcx.ensure_ok().generics_of(def_id); + self.tcx.ensure_ok().predicates_of(def_id); + self.tcx.ensure_ok().explicit_item_bounds(def_id); + self.tcx.ensure_ok().explicit_item_self_bounds(def_id); + self.tcx.ensure_ok().item_bounds(def_id); + self.tcx.ensure_ok().item_self_bounds(def_id); if self.tcx.is_conditionally_const(def_id) { - self.tcx.ensure().explicit_implied_const_bounds(def_id); - self.tcx.ensure().const_conditions(def_id); + self.tcx.ensure_ok().explicit_implied_const_bounds(def_id); + self.tcx.ensure_ok().const_conditions(def_id); } intravisit::walk_opaque_ty(self, opaque); } @@ -683,20 +683,20 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ItemKind::ForeignMod { items, .. } => { for item in *items { let item = tcx.hir().foreign_item(item.id); - tcx.ensure().generics_of(item.owner_id); - tcx.ensure().type_of(item.owner_id); - tcx.ensure().predicates_of(item.owner_id); + tcx.ensure_ok().generics_of(item.owner_id); + tcx.ensure_ok().type_of(item.owner_id); + tcx.ensure_ok().predicates_of(item.owner_id); if tcx.is_conditionally_const(def_id) { - tcx.ensure().explicit_implied_const_bounds(def_id); - tcx.ensure().const_conditions(def_id); + tcx.ensure_ok().explicit_implied_const_bounds(def_id); + tcx.ensure_ok().const_conditions(def_id); } match item.kind { hir::ForeignItemKind::Fn(..) => { - tcx.ensure().codegen_fn_attrs(item.owner_id); - tcx.ensure().fn_sig(item.owner_id) + tcx.ensure_ok().codegen_fn_attrs(item.owner_id); + tcx.ensure_ok().fn_sig(item.owner_id) } hir::ForeignItemKind::Static(..) => { - tcx.ensure().codegen_fn_attrs(item.owner_id); + tcx.ensure_ok().codegen_fn_attrs(item.owner_id); let mut visitor = HirPlaceholderCollector::default(); visitor.visit_foreign_item(item); placeholder_type_error( @@ -713,40 +713,40 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } } hir::ItemKind::Enum(..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); lower_enum_variant_types(tcx, def_id.to_def_id()); } hir::ItemKind::Impl { .. } => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().impl_trait_header(def_id); - tcx.ensure().predicates_of(def_id); - tcx.ensure().associated_items(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().impl_trait_header(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().associated_items(def_id); } hir::ItemKind::Trait(..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().trait_def(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().trait_def(def_id); tcx.at(it.span).explicit_super_predicates_of(def_id); - tcx.ensure().predicates_of(def_id); - tcx.ensure().associated_items(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().associated_items(def_id); } hir::ItemKind::TraitAlias(..) => { - tcx.ensure().generics_of(def_id); + tcx.ensure_ok().generics_of(def_id); tcx.at(it.span).explicit_implied_predicates_of(def_id); tcx.at(it.span).explicit_super_predicates_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); for f in struct_def.fields() { - tcx.ensure().generics_of(f.def_id); - tcx.ensure().type_of(f.def_id); - tcx.ensure().predicates_of(f.def_id); + tcx.ensure_ok().generics_of(f.def_id); + tcx.ensure_ok().type_of(f.def_id); + tcx.ensure_ok().predicates_of(f.def_id); } if let Some(ctor_def_id) = struct_def.ctor_def_id() { @@ -755,15 +755,15 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } hir::ItemKind::TyAlias(..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_item(it); @@ -779,11 +779,11 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } hir::ItemKind::Fn { .. } => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); - tcx.ensure().fn_sig(def_id); - tcx.ensure().codegen_fn_attrs(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); } } } @@ -791,18 +791,18 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { let trait_item = tcx.hir().trait_item(trait_item_id); let def_id = trait_item_id.owner_id; - tcx.ensure().generics_of(def_id); + tcx.ensure_ok().generics_of(def_id); let icx = ItemCtxt::new(tcx, def_id.def_id); match trait_item.kind { hir::TraitItemKind::Fn(..) => { - tcx.ensure().codegen_fn_attrs(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().fn_sig(def_id); } hir::TraitItemKind::Const(ty, body_id) => { - tcx.ensure().type_of(def_id); + tcx.ensure_ok().type_of(def_id); if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType) && !(ty.is_suggestable_infer_ty() && body_id.is_some()) { @@ -821,9 +821,9 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { } hir::TraitItemKind::Type(_, Some(_)) => { - tcx.ensure().item_bounds(def_id); - tcx.ensure().item_self_bounds(def_id); - tcx.ensure().type_of(def_id); + tcx.ensure_ok().item_bounds(def_id); + tcx.ensure_ok().item_self_bounds(def_id); + tcx.ensure_ok().type_of(def_id); // Account for `type T = _;`. let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); @@ -838,8 +838,8 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { } hir::TraitItemKind::Type(_, None) => { - tcx.ensure().item_bounds(def_id); - tcx.ensure().item_self_bounds(def_id); + tcx.ensure_ok().item_bounds(def_id); + tcx.ensure_ok().item_self_bounds(def_id); // #74612: Visit and try to find bad placeholders // even if there is no concrete type. let mut visitor = HirPlaceholderCollector::default(); @@ -856,20 +856,20 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { } }; - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { let def_id = impl_item_id.owner_id; - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); let impl_item = tcx.hir().impl_item(impl_item_id); let icx = ItemCtxt::new(tcx, def_id.def_id); match impl_item.kind { hir::ImplItemKind::Fn(..) => { - tcx.ensure().codegen_fn_attrs(def_id); - tcx.ensure().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); + tcx.ensure_ok().fn_sig(def_id); } hir::ImplItemKind::Type(_) => { // Account for `type T = _;` @@ -904,9 +904,9 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { } fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { @@ -937,9 +937,9 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { ); for f in &variant.fields { - tcx.ensure().generics_of(f.did); - tcx.ensure().type_of(f.did); - tcx.ensure().predicates_of(f.did); + tcx.ensure_ok().generics_of(f.did); + tcx.ensure_ok().type_of(f.did); + tcx.ensure_ok().predicates_of(f.did); } // Lower the ctor, if any. This also registers the variant as an item. diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index fd5a7089b4cf8..c30b39dfe7656 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -62,7 +62,7 @@ pub(crate) fn check_impl_wf( // Check that the args are constrained. We queryfied the check for ty/const params // since unconstrained type/const params cause ICEs in projection, so we want to // detect those specifically and project those to `TyKind::Error`. - let mut res = tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id); + let mut res = tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id); res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id)); if tcx.features().min_specialization() { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index ae054a9eaeb7a..3af4318544e96 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -100,7 +100,7 @@ use rustc_middle::middle; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits; pub use crate::collect::suggest_impl_trait; @@ -139,16 +139,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); tcx.sess.time("coherence_checking", || { + // When discarding query call results, use an explicit type to indicate + // what we are intending to discard, to help future type-based refactoring. + type R = Result<(), ErrorGuaranteed>; + tcx.hir().par_for_each_module(|module| { - let _ = tcx.ensure().check_mod_type_wf(module); + let _: R = tcx.ensure_ok().check_mod_type_wf(module); }); for &trait_def_id in tcx.all_local_trait_impls(()).keys() { - let _ = tcx.ensure().coherent_trait(trait_def_id); + let _: R = tcx.ensure_ok().coherent_trait(trait_def_id); } // these queries are executed for side-effects (error reporting): - let _ = tcx.ensure().crate_inherent_impls_validity_check(()); - let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); + let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(()); + let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(()); }); if tcx.features().rustc_attrs() { @@ -167,12 +171,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.hir().par_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { - DefKind::Static { .. } => tcx.ensure().eval_static_initializer(item_def_id), + DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id), DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::fully_monomorphized(); - tcx.ensure().eval_to_const_value_raw(typing_env.as_query_input(cid)); + tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); } _ => (), } @@ -185,11 +189,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.hir().par_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); if !matches!(def_kind, DefKind::AnonConst) { - tcx.ensure().typeck(item_def_id); + tcx.ensure_ok().typeck(item_def_id); } }); - tcx.ensure().check_unused_traits(()); + tcx.ensure_ok().check_unused_traits(()); } /// Lower a [`hir::Ty`] to a [`Ty`]. diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 28b1a823daea0..edc3702d90b58 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -49,7 +49,7 @@ pub(crate) fn check_legal_trait_for_method_call( }; return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg })); } - tcx.ensure().coherent_trait(trait_id) + tcx.ensure_ok().coherent_trait(trait_id) } #[derive(Debug)] 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_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 0b91c023cfc87..0324ebf9fd21e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -832,20 +832,20 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { sess.time("misc_checking_1", || { parallel!( { - sess.time("looking_for_entry_point", || tcx.ensure().entry_fn(())); + sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(())); sess.time("looking_for_derive_registrar", || { - tcx.ensure().proc_macro_decls_static(()) + tcx.ensure_ok().proc_macro_decls_static(()) }); CStore::from_tcx(tcx).report_unused_deps(tcx); }, { tcx.hir().par_for_each_module(|module| { - tcx.ensure().check_mod_loops(module); - tcx.ensure().check_mod_attrs(module); - tcx.ensure().check_mod_naked_functions(module); - tcx.ensure().check_mod_unstable_api_usage(module); + tcx.ensure_ok().check_mod_loops(module); + tcx.ensure_ok().check_mod_attrs(module); + tcx.ensure_ok().check_mod_naked_functions(module); + tcx.ensure_ok().check_mod_unstable_api_usage(module); }); }, { @@ -858,8 +858,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // since they might not otherwise get called. // This marks the corresponding crate-level attributes // as used, and ensures that their values are valid. - tcx.ensure().limits(()); - tcx.ensure().stability_index(()); + tcx.ensure_ok().limits(()); + tcx.ensure_ok().stability_index(()); } ); }); @@ -868,7 +868,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { sess.time("MIR_coroutine_by_move_body", || { tcx.hir().par_body_owners(|def_id| { if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) { - tcx.ensure_with_value().coroutine_by_move_body_def_id(def_id); + tcx.ensure_done().coroutine_by_move_body_def_id(def_id); } }); }); @@ -883,13 +883,13 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.hir().par_body_owners(|def_id| { // Run unsafety check because it's responsible for stealing and // deallocating THIR. - tcx.ensure().check_unsafety(def_id); - tcx.ensure().mir_borrowck(def_id) + tcx.ensure_ok().check_unsafety(def_id); + tcx.ensure_ok().mir_borrowck(def_id) }); }); sess.time("MIR_effect_checking", || { tcx.hir().par_body_owners(|def_id| { - tcx.ensure().has_ffi_unwind_calls(def_id); + tcx.ensure_ok().has_ffi_unwind_calls(def_id); // If we need to codegen, ensure that we emit all errors from // `mir_drops_elaborated_and_const_checked` now, to avoid discovering @@ -897,15 +897,15 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { if tcx.sess.opts.output_types.should_codegen() || tcx.hir().body_const_context(def_id).is_some() { - tcx.ensure().mir_drops_elaborated_and_const_checked(def_id); + tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id); } }); }); sess.time("coroutine_obligations", || { tcx.hir().par_body_owners(|def_id| { if tcx.is_coroutine(def_id.to_def_id()) { - tcx.ensure().mir_coroutine_witnesses(def_id); - tcx.ensure().check_coroutine_obligations( + tcx.ensure_ok().mir_coroutine_witnesses(def_id); + tcx.ensure_ok().check_coroutine_obligations( tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), ); } @@ -950,15 +950,16 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { sess.time("misc_checking_3", || { parallel!( { - tcx.ensure().effective_visibilities(()); + tcx.ensure_ok().effective_visibilities(()); parallel!( { - tcx.ensure().check_private_in_public(()); + tcx.ensure_ok().check_private_in_public(()); }, { - tcx.hir() - .par_for_each_module(|module| tcx.ensure().check_mod_deathness(module)); + tcx.hir().par_for_each_module(|module| { + tcx.ensure_ok().check_mod_deathness(module) + }); }, { sess.time("lint_checking", || { @@ -966,14 +967,14 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { }); }, { - tcx.ensure().clashing_extern_declarations(()); + tcx.ensure_ok().clashing_extern_declarations(()); } ); }, { sess.time("privacy_checking_modules", || { tcx.hir().par_for_each_module(|module| { - tcx.ensure().check_mod_privacy(module); + tcx.ensure_ok().check_mod_privacy(module); }); }); } @@ -981,7 +982,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { // This check has to be run after all lints are done processing. We don't // define a lint filter, as all lint checks should have finished at this point. - sess.time("check_lint_expectations", || tcx.ensure().check_expectations(None)); + sess.time("check_lint_expectations", || tcx.ensure_ok().check_expectations(None)); // This query is only invoked normally if a diagnostic is emitted that needs any // diagnostic item. If the crate compiles without checking any diagnostic items, @@ -1006,7 +1007,7 @@ fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { ) }) => { - tcx.ensure().trigger_delayed_bug(def_id); + tcx.ensure_ok().trigger_delayed_bug(def_id); } // Bare `#[rustc_error]`. diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index c6d7b839e1970..826ecc22c24ba 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -458,7 +458,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { || { tcx.sess.time("module_lints", || { // Run per-module lints - tcx.hir().par_for_each_module(|module| tcx.ensure().lint_mod(module)); + tcx.hir().par_for_each_module(|module| tcx.ensure_ok().lint_mod(module)); }); }, ); diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 88ea6e07d6eb6..62bf34ad5adce 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -118,11 +118,17 @@ struct QueryModifiers { /// Generate a `feed` method to set the query's value from another query. feedable: Option, - /// Forward the result on ensure if the query gets recomputed, and - /// return `Ok(())` otherwise. Only applicable to queries returning - /// `Result`. The `T` is not returned from `ensure` - /// invocations. - ensure_forwards_result_if_red: Option, + /// When this query is called via `tcx.ensure_ok()`, it returns + /// `Result<(), ErrorGuaranteed>` instead of `()`. If the query needs to + /// be executed, and that execution returns an error, the error result is + /// returned to the caller. + /// + /// If execution is skipped, a synthetic `Ok(())` is returned, on the + /// assumption that a query with all-green inputs must have succeeded. + /// + /// Can only be applied to queries with a return value of + /// `Result<_, ErrorGuaranteed>`. + return_result_from_ensure_ok: Option, } fn parse_query_modifiers(input: ParseStream<'_>) -> Result { @@ -138,7 +144,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { let mut depth_limit = None; let mut separate_provide_extern = None; let mut feedable = None; - let mut ensure_forwards_result_if_red = None; + let mut return_result_from_ensure_ok = None; while !input.is_empty() { let modifier: Ident = input.parse()?; @@ -200,8 +206,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { try_insert!(separate_provide_extern = modifier); } else if modifier == "feedable" { try_insert!(feedable = modifier); - } else if modifier == "ensure_forwards_result_if_red" { - try_insert!(ensure_forwards_result_if_red = modifier); + } else if modifier == "return_result_from_ensure_ok" { + try_insert!(return_result_from_ensure_ok = modifier); } else { return Err(Error::new(modifier.span(), "unknown query modifier")); } @@ -222,7 +228,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { depth_limit, separate_provide_extern, feedable, - ensure_forwards_result_if_red, + return_result_from_ensure_ok, }) } @@ -354,7 +360,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { eval_always, depth_limit, separate_provide_extern, - ensure_forwards_result_if_red, + return_result_from_ensure_ok, ); if modifiers.cache.is_some() { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index da07ad8f6c074..5fcb9c8503566 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -165,7 +165,7 @@ macro_rules! provide_one { // doesn't need to do this (and can't, as it would cause a query cycle). use rustc_middle::dep_graph::dep_kinds; if dep_kinds::$name != dep_kinds::crate_hash && $tcx.dep_graph.is_fully_enabled() { - $tcx.ensure().crate_hash($def_id.krate); + $tcx.ensure_ok().crate_hash($def_id.krate); } let cdata = rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx($tcx), |c| { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 43372154b2ce4..6e562e457d212 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2191,13 +2191,13 @@ fn prefetch_mir(tcx: TyCtxt<'_>) { let (encode_const, encode_opt) = should_encode_mir(tcx, reachable_set, def_id); if encode_const { - tcx.ensure_with_value().mir_for_ctfe(def_id); + tcx.ensure_done().mir_for_ctfe(def_id); } if encode_opt { - tcx.ensure_with_value().optimized_mir(def_id); + tcx.ensure_done().optimized_mir(def_id); } if encode_opt || encode_const { - tcx.ensure_with_value().promoted_mir(def_id); + tcx.ensure_done().promoted_mir(def_id); } }) } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 4c47d9636d3f2..78749428c6df3 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -9,7 +9,7 @@ use super::{ ReportedErrorInfo, }; use crate::mir; -use crate::query::TyCtxtEnsure; +use crate::query::TyCtxtEnsureOk; use crate::ty::visit::TypeVisitableExt; use crate::ty::{self, GenericArgs, TyCtxt}; @@ -198,7 +198,7 @@ impl<'tcx> TyCtxt<'tcx> { } } -impl<'tcx> TyCtxtEnsure<'tcx> { +impl<'tcx> TyCtxtEnsureOk<'tcx> { /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts /// that can't take any generic arguments like const items or enum discriminants. If a /// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 41e9858030c8f..6c442fc1047fa 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -91,7 +91,7 @@ pub use keys::{AsLocalKey, Key, LocalCrate}; pub mod on_disk_cache; #[macro_use] pub mod plumbing; -pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue}; +pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk}; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method @@ -1087,7 +1087,7 @@ rustc_queries! { query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) } - ensure_forwards_result_if_red + return_result_from_ensure_ok } /// Caches `CoerceUnsized` kinds for impls on custom types. @@ -1095,7 +1095,7 @@ rustc_queries! { desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern - ensure_forwards_result_if_red + return_result_from_ensure_ok } query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { @@ -1110,7 +1110,7 @@ rustc_queries! { query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) } - ensure_forwards_result_if_red + return_result_from_ensure_ok } /// Borrow-checks the function body. If this is a closure, returns @@ -1140,7 +1140,7 @@ rustc_queries! { /// query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for inherent impls that should not be defined in crate" } - ensure_forwards_result_if_red + return_result_from_ensure_ok } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. @@ -1152,7 +1152,7 @@ rustc_queries! { /// query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for overlap between inherent impls defined in this crate" } - ensure_forwards_result_if_red + return_result_from_ensure_ok } /// Checks whether all impls in the crate pass the overlap check, returning @@ -1162,7 +1162,7 @@ rustc_queries! { "checking whether impl `{}` follows the orphan rules", tcx.def_path_str(key), } - ensure_forwards_result_if_red + return_result_from_ensure_ok } /// Check whether the function has any recursion that could cause the inliner to trigger @@ -1479,7 +1479,7 @@ rustc_queries! { query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> { desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) } cache_on_disk_if { true } - ensure_forwards_result_if_red + return_result_from_ensure_ok } query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] { desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) } @@ -1715,12 +1715,12 @@ rustc_queries! { query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } - ensure_forwards_result_if_red + return_result_from_ensure_ok } query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) } - ensure_forwards_result_if_red + return_result_from_ensure_ok } // The `DefId`s of all non-generic functions and statics in the given crate @@ -2442,7 +2442,7 @@ rustc_queries! { /// Any other def id will ICE. query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) } - ensure_forwards_result_if_red + return_result_from_ensure_ok } query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] { diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 1c157f33a813b..6c019b427dbd1 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -88,30 +88,68 @@ impl<'tcx> Deref for TyCtxtAt<'tcx> { } #[derive(Copy, Clone)] -pub struct TyCtxtEnsure<'tcx> { +#[must_use] +pub struct TyCtxtEnsureOk<'tcx> { pub tcx: TyCtxt<'tcx>, } #[derive(Copy, Clone)] -pub struct TyCtxtEnsureWithValue<'tcx> { +#[must_use] +pub struct TyCtxtEnsureDone<'tcx> { pub tcx: TyCtxt<'tcx>, } impl<'tcx> TyCtxt<'tcx> { - /// Returns a transparent wrapper for `TyCtxt`, which ensures queries - /// are executed instead of just returning their results. + /// Wrapper that calls queries in a special "ensure OK" mode, for callers + /// that don't need the return value and just want to invoke a query for + /// its potential side-effect of emitting fatal errors. + /// + /// This can be more efficient than a normal query call, because if the + /// query's inputs are all green, the call can return immediately without + /// needing to obtain a value (by decoding one from disk or by executing + /// the query). + /// + /// (As with all query calls, execution is also skipped if the query result + /// is already cached in memory.) + /// + /// ## WARNING + /// A subsequent normal call to the same query might still cause it to be + /// executed! This can occur when the inputs are all green, but the query's + /// result is not cached on disk, so the query must be executed to obtain a + /// return value. + /// + /// Therefore, this call mode is not appropriate for callers that want to + /// ensure that the query is _never_ executed in the future. + /// + /// ## `return_result_from_ensure_ok` + /// If a query has the `return_result_from_ensure_ok` modifier, calls via + /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the + /// query needs to be executed, and execution returns an error, that error + /// is returned to the caller. #[inline(always)] - pub fn ensure(self) -> TyCtxtEnsure<'tcx> { - TyCtxtEnsure { tcx: self } + pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> { + TyCtxtEnsureOk { tcx: self } } - /// Returns a transparent wrapper for `TyCtxt`, which ensures queries - /// are executed instead of just returning their results. + /// Wrapper that calls queries in a special "ensure done" mode, for callers + /// that don't need the return value and just want to guarantee that the + /// query won't be executed in the future, by executing it now if necessary. /// - /// This version verifies that the computed result exists in the cache before returning. + /// This is useful for queries that read from a [`Steal`] value, to ensure + /// that they are executed before the query that will steal the value. + /// + /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be + /// skipped if its return value is stored in the disk-cache. This is still + /// more efficient than a regular query, because in that situation the + /// return value doesn't necessarily need to be decoded. + /// + /// (As with all query calls, execution is also skipped if the query result + /// is already cached in memory.) + /// + /// [`Steal`]: rustc_data_structures::steal::Steal #[inline(always)] - pub fn ensure_with_value(self) -> TyCtxtEnsureWithValue<'tcx> { - TyCtxtEnsureWithValue { tcx: self } + pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> { + TyCtxtEnsureDone { tcx: self } } /// Returns a transparent wrapper for `TyCtxt` which uses @@ -193,7 +231,7 @@ macro_rules! query_ensure { ([]$($args:tt)*) => { query_ensure($($args)*) }; - ([(ensure_forwards_result_if_red) $($rest:tt)*]$($args:tt)*) => { + ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => { query_ensure_error_guaranteed($($args)*).map(|_| ()) }; ([$other:tt $($modifiers:tt)*]$($args:tt)*) => { @@ -248,15 +286,15 @@ macro_rules! separate_provide_extern_decl { }; } -macro_rules! ensure_result { - ([][$ty:ty]) => { +macro_rules! ensure_ok_result { + ( [] ) => { () }; - ([(ensure_forwards_result_if_red) $($rest:tt)*][$ty:ty]) => { + ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => { Result<(), ErrorGuaranteed> }; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - ensure_result!([$($modifiers)*][$($args)*]) + ( [$other:tt $($modifiers:tt)*] ) => { + ensure_ok_result!( [$($modifiers)*] ) }; } @@ -383,10 +421,13 @@ macro_rules! define_callbacks { $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)* } - impl<'tcx> TyCtxtEnsure<'tcx> { + impl<'tcx> TyCtxtEnsureOk<'tcx> { $($(#[$attr])* #[inline(always)] - pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> ensure_result!([$($modifiers)*][$V]) { + pub fn $name( + self, + key: query_helper_param_ty!($($K)*), + ) -> ensure_ok_result!([$($modifiers)*]) { query_ensure!( [$($modifiers)*] self.tcx, @@ -398,7 +439,7 @@ macro_rules! define_callbacks { })* } - impl<'tcx> TyCtxtEnsureWithValue<'tcx> { + impl<'tcx> TyCtxtEnsureDone<'tcx> { $($(#[$attr])* #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 69f6fc0ad8a66..522a553d2432e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1957,7 +1957,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap { // Create a dependency to the crate to be sure we re-execute this when the amount of // definitions change. - self.ensure().hir_crate(()); + self.ensure_ok().hir_crate(()); // Freeze definitions once we start iterating on them, to prevent adding new ones // while iterating. If some query needs to add definitions, it should be `ensure`d above. self.untracked.definitions.freeze().def_path_hash_to_def_index_map() 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_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 7d5e5c2e82370..318bd0c7ec020 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -367,7 +367,7 @@ impl<'tcx> TyCtxt<'tcx> { validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>, ) -> Option { let drop_trait = self.lang_items().drop_trait()?; - self.ensure().coherent_trait(drop_trait).ok()?; + self.ensure_ok().coherent_trait(drop_trait).ok()?; let ty = self.type_of(adt_did).instantiate_identity(); let mut dtor_candidate = None; @@ -404,7 +404,7 @@ impl<'tcx> TyCtxt<'tcx> { validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>, ) -> Option { let async_drop_trait = self.lang_items().async_drop_trait()?; - self.ensure().coherent_trait(async_drop_trait).ok()?; + self.ensure_ok().coherent_trait(async_drop_trait).ok()?; let ty = self.type_of(adt_did).instantiate_identity(); let mut dtor_candidate = None; 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/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 93fb9873e80ab..e04c70b588377 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -47,7 +47,7 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>( /// Create the MIR for a given `DefId`, including unreachable code. Do not call /// this directly; instead use the cached version via `mir_built`. pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { - tcx.ensure_with_value().thir_abstract_const(def); + tcx.ensure_done().thir_abstract_const(def); if let Err(e) = tcx.check_match(def) { return construct_error(tcx, def, e); } @@ -68,7 +68,7 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { // "not all control paths return a value" is reported here. // // maybe move the check to a MIR pass? - tcx.ensure().check_liveness(def); + tcx.ensure_ok().check_liveness(def); // Don't steal here, instead steal in unsafeck. This is so that // pattern inline constants can be evaluated as part of building the diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 995bc311b7c48..0cca0a43143fd 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -200,7 +200,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { fn visit_inner_body(&mut self, def: LocalDefId) { if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) { // Runs all other queries that depend on THIR. - self.tcx.ensure_with_value().mir_built(def); + self.tcx.ensure_done().mir_built(def); let inner_thir = &inner_thir.steal(); let hir_context = self.tcx.local_def_id_to_hir_id(def); let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe); @@ -1112,7 +1112,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { let Ok((thir, expr)) = tcx.thir_body(def) else { return }; // Runs all other queries that depend on THIR. - tcx.ensure_with_value().mir_built(def); + tcx.ensure_done().mir_built(def); let thir = &thir.steal(); let hir_id = tcx.local_def_id_to_hir_id(def); 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_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 95aeccfdda66b..f8b0688dfdcc0 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -4,7 +4,7 @@ use std::iter; use std::ops::{Range, RangeFrom}; use rustc_abi::{ExternAbi, FieldIdx}; -use rustc_attr_parsing::InlineAttr; +use rustc_attr_parsing::{InlineAttr, OptimizeAttr}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_index::Idx; @@ -770,6 +770,10 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>( return Err("never inline attribute"); } + if let OptimizeAttr::DoNotOptimize = callee_attrs.optimize { + return Err("has DoNotOptimize attribute"); + } + // Reachability pass defines which functions are eligible for inlining. Generally inlining // other functions is incorrect because they could reference symbols that aren't exported. let is_generic = callsite.callee.args.non_erasable_generics().next().is_some(); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 4af9a111bdf98..b572f6ca0b36a 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -421,11 +421,11 @@ fn mir_promoted( }; // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run. - tcx.ensure_with_value().has_ffi_unwind_calls(def); + tcx.ensure_done().has_ffi_unwind_calls(def); // the `by_move_body` query uses the raw mir, so make sure it is run. if tcx.needs_coroutine_by_move_body_def_id(def.to_def_id()) { - tcx.ensure_with_value().coroutine_by_move_body_def_id(def); + tcx.ensure_done().coroutine_by_move_body_def_id(def); } let mut body = tcx.mir_built(def).steal(); @@ -488,7 +488,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { /// end up missing the source MIR due to stealing happening. fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { if tcx.is_coroutine(def.to_def_id()) { - tcx.ensure_with_value().mir_coroutine_witnesses(def); + tcx.ensure_done().mir_coroutine_witnesses(def); } // We only need to borrowck non-synthetic MIR. @@ -501,7 +501,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & if pm::should_run_pass(tcx, &inline::Inline, pm::Optimizations::Allowed) || inline::ForceInline::should_run_pass_for_callee(tcx, def.to_def_id()) { - tcx.ensure_with_value().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id())); + tcx.ensure_done().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id())); } } @@ -733,7 +733,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { // Run the `mir_for_ctfe` query, which depends on `mir_drops_elaborated_and_const_checked` // which we are going to steal below. Thus we need to run `mir_for_ctfe` first, so it // computes and caches its result. - Some(hir::ConstContext::ConstFn) => tcx.ensure_with_value().mir_for_ctfe(did), + Some(hir::ConstContext::ConstFn) => tcx.ensure_done().mir_for_ctfe(did), None => {} Some(other) => panic!("do not use `optimized_mir` for constants: {other:?}"), } @@ -772,7 +772,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec( mode: CollectionMode, ) -> (MonoItems<'tcx>, MonoItems<'tcx>) { // This item is getting monomorphized, do mono-time checks. - tcx.ensure().check_mono_item(instance); + tcx.ensure_ok().check_mono_item(instance); let body = tcx.instance_mir(instance.def); // Naively, in "used" collection mode, all functions get added to *both* `used_items` and 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..6beb108bc3aee 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()); @@ -179,7 +180,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return e; } - if let Err(guar) = self.tcx.ensure().coherent_trait(trait_pred.def_id()) { + if let Err(guar) = self.tcx.ensure_ok().coherent_trait(trait_pred.def_id()) { // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. return guar; @@ -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 { @@ -511,8 +513,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return e; } - if let Err(guar) = - self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id)) + if let Err(guar) = self + .tcx + .ensure_ok() + .coherent_trait(self.tcx.parent(data.projection_term.def_id)) { // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. @@ -524,6 +528,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 +544,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 +569,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 +594,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 +608,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 b4e5cc6185cf0..658fb4009d508 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/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 401b41c796dad..cb3e81f5477fc 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -575,7 +575,7 @@ fn report_conflicting_impls<'tcx>( match used_to_be_allowed { None => { let reported = if overlap.with_impl.is_local() - || tcx.ensure().orphan_check_impl(impl_def_id).is_ok() + || tcx.ensure_ok().orphan_check_impl(impl_def_id).is_ok() { let mut err = tcx.dcx().struct_span_err(impl_span, msg()); err.code(E0119); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index c351cf5aaac61..f39c611d19fe0 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -379,7 +379,7 @@ pub(crate) fn assoc_def( // Ensure that the impl is constrained, otherwise projection may give us // bad unconstrained infer vars. if let Some(impl_def_id) = impl_def_id.as_local() { - tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?; + tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?; } let item = tcx.associated_item(impl_item_id); @@ -402,7 +402,7 @@ pub(crate) fn assoc_def( if assoc_item.item.container == ty::AssocItemContainer::Impl && let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local() { - tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?; + tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?; } Ok(assoc_item) diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index d5e1937efaa45..8c6e3c86bf5c8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -225,7 +225,7 @@ fn resolve_associated_item<'tcx>( if trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.ensure().compare_impl_item(leaf_def_item)?; + tcx.ensure_ok().compare_impl_item(leaf_def_item)?; } Some(ty::Instance::new(leaf_def.item.def_id, args)) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index f447d186a5242..cd3558ac6a49b 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -339,7 +339,7 @@ fn copy_self_contained_objects( // to using gcc from a glibc-targeting toolchain for linking. // To do that we have to distribute musl startup objects as a part of Rust toolchain // and link with them manually in the self-contained mode. - if target.contains("musl") && !target.contains("unikraft") { + if target.needs_crt_begin_end() { let srcdir = builder.musl_libdir(target).unwrap_or_else(|| { panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple) }); diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 3cf25373b8963..82779dc630634 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -1295,7 +1295,9 @@ impl Step for CrtBeginEnd { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(CrtBeginEnd { target: run.target }); + if run.target.needs_crt_begin_end() { + run.builder.ensure(CrtBeginEnd { target: run.target }); + } } /// Build crtbegin.o/crtend.o for musl target. diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 98490118f7d62..eb1c15b84f3a1 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -575,6 +575,10 @@ impl TargetSelection { env::var("OSTYPE").is_ok_and(|v| v.to_lowercase().contains("cygwin")) } + pub fn needs_crt_begin_end(&self) -> bool { + self.contains("musl") && !self.contains("unikraft") + } + /// Path to the file defining the custom target, if any. pub fn filepath(&self) -> Option<&Path> { self.file.as_ref().map(Path::new) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 9af887096251c..c249d430b2782 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -525,8 +525,7 @@ auto: env: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). + # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions NO_DOWNLOAD_CI_LLVM: 1 <<: *job-windows-25-8c @@ -535,8 +534,7 @@ auto: env: SCRIPT: make ci-mingw-x RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). + # There is no dist-x86_64-mingw-alt, so there is no prebuilt LLVM with assertions NO_DOWNLOAD_CI_LLVM: 1 <<: *job-windows @@ -544,8 +542,7 @@ auto: env: SCRIPT: make ci-mingw-bootstrap RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). + # There is no dist-x86_64-mingw-alt, so there is no prebuilt LLVM with assertions NO_DOWNLOAD_CI_LLVM: 1 <<: *job-windows @@ -593,9 +590,6 @@ auto: RUST_CONFIGURE_ARGS: >- --build=i686-pc-windows-gnu --enable-full-tools - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). - NO_DOWNLOAD_CI_LLVM: 1 SCRIPT: python x.py dist bootstrap --include-default-paths DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift @@ -607,9 +601,6 @@ auto: RUST_CONFIGURE_ARGS: >- --build=x86_64-pc-windows-gnu --enable-full-tools - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). - NO_DOWNLOAD_CI_LLVM: 1 DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift <<: *job-windows diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 0437ebb585768..a072b1256f479 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -336,14 +336,14 @@ pub(crate) fn run_global_ctxt( // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes. let _ = tcx.sess.time("wf_checking", || { - tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module)) + tcx.hir().try_par_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module)) }); tcx.dcx().abort_if_errors(); tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx)); tcx.sess.time("check_mod_attrs", || { - tcx.hir().for_each_module(|module| tcx.ensure().check_mod_attrs(module)) + tcx.hir().for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module)) }); rustc_passes::stability::check_unused_or_stable_features(tcx); diff --git a/src/tools/clippy/clippy_lints/src/ctfe.rs b/src/tools/clippy/clippy_lints/src/ctfe.rs index 589b99518a09b..7bae04a10f10b 100644 --- a/src/tools/clippy/clippy_lints/src/ctfe.rs +++ b/src/tools/clippy/clippy_lints/src/ctfe.rs @@ -21,6 +21,6 @@ impl<'tcx> LateLintPass<'tcx> for ClippyCtfe { _: Span, defid: LocalDefId, ) { - cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint + cx.tcx.ensure_ok().mir_drops_elaborated_and_const_checked(defid); // Lint } } diff --git a/tests/codegen/issues/issue-136329-optnone-noinline.rs b/tests/codegen/issues/issue-136329-optnone-noinline.rs new file mode 100644 index 0000000000000..57c9e47a4992a --- /dev/null +++ b/tests/codegen/issues/issue-136329-optnone-noinline.rs @@ -0,0 +1,21 @@ +//! Ensure that `#[optimize(none)]` functions are never inlined + +//@ compile-flags: -Copt-level=3 + +#![feature(optimize_attribute)] + +#[optimize(none)] +pub fn foo() { + let _x = 123; +} + +// CHECK-LABEL: define{{.*}}void @bar +// CHECK: start: +// CHECK: {{.*}}call {{.*}}void +// CHECK: ret void +#[no_mangle] +pub fn bar() { + foo(); +} + +fn main() {} 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}>`