From 2db126d651b6803c9b37fd021376ce6e5dd5a09e Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sat, 1 Mar 2025 22:27:16 +0000 Subject: Include whitespace in "remove `|`" suggestion and make it hidden --- compiler/rustc_errors/src/diagnostic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 96c7ba6ed27..0034a30be08 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1112,7 +1112,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { .map(|snippet| { debug_assert!( !(sp.is_empty() && snippet.is_empty()), - "Span must not be empty and have no suggestion" + "Span `{sp:?}` must not be empty and have no suggestion" ); Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] } }) -- cgit 1.4.1-3-g733a5 From 99196657fcb5c1e20c13e76166c7f52d35584e88 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 16 Jul 2025 19:45:07 +0000 Subject: Use `tcx.short_string()` in more diagnostics `TyCtxt::short_string` ensures that user visible type paths aren't overwhelming on the terminal output, and properly saves the long name to disk as a side-channel. We already use these throughout the compiler and have been using them as needed when users find cases where the output is verbose. This is a proactive search of some cases to use `short_string`. We add support for shortening the path of "trait path only". Every manual use of `short_string` is a bright marker that that error should be using structured diagnostics instead (as they have proper handling of long types without the maintainer having to think abou tthem). When we don't actually print out a shortened type we don't need the "use `--verbose`" note. On E0599 show type identity to avoid expanding the receiver's generic parameters. Unify wording on `long_ty_path` everywhere. --- compiler/rustc_errors/src/diagnostic.rs | 5 + .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 5 +- compiler/rustc_hir_typeck/messages.ftl | 4 +- compiler/rustc_hir_typeck/src/errors.rs | 8 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 125 +++++++++------------ compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_trait_selection/messages.ftl | 2 - .../src/error_reporting/infer/mod.rs | 15 +-- .../src/error_reporting/infer/need_type_info.rs | 32 ++---- .../src/error_reporting/traits/ambiguity.rs | 57 +++++----- .../error_reporting/traits/fulfillment_errors.rs | 119 +++++++++++++------- .../src/error_reporting/traits/on_unimplemented.rs | 4 +- .../src/error_reporting/traits/suggestions.rs | 67 +++++++---- compiler/rustc_trait_selection/src/errors.rs | 11 -- .../attributes/rustc_confusables_std_cases.stderr | 6 +- tests/ui/codegen/overflow-during-mono.rs | 3 +- tests/ui/codegen/overflow-during-mono.stderr | 10 +- .../ui/confuse-field-and-method/issue-18343.stderr | 2 +- .../ui/confuse-field-and-method/issue-2392.stderr | 12 +- ...t_body_owner_parent_found_in_diagnostics.stderr | 2 +- .../ui/dropck/dropck_no_diverge_on_nonregular_1.rs | 1 + .../dropck_no_diverge_on_nonregular_1.stderr | 6 +- .../never-type-fallback-breaking.e2024.stderr | 8 +- tests/ui/error-codes/E0275.rs | 1 + tests/ui/error-codes/E0275.stderr | 8 +- .../trait-bounds/hrtb-doesnt-borrow-self-2.rs | 2 + .../trait-bounds/hrtb-doesnt-borrow-self-2.stderr | 16 +-- .../auto-trait-leakage/auto-trait-leak2.rs | 1 + .../auto-trait-leakage/auto-trait-leak2.stderr | 16 +-- ...-in-let-binding-without-sufficient-type-info.rs | 1 + ...let-binding-without-sufficient-type-info.stderr | 6 +- .../ui/interior-mutability/interior-mutability.rs | 1 + .../interior-mutability/interior-mutability.stderr | 4 +- tests/ui/issues/issue-41880.stderr | 2 +- tests/ui/methods/call_method_unknown_referent.rs | 2 +- .../ui/methods/call_method_unknown_referent.stderr | 2 +- tests/ui/methods/inherent-bound-in-probe.rs | 1 + tests/ui/methods/inherent-bound-in-probe.stderr | 12 +- .../method-not-found-generic-arg-elision.stderr | 8 +- tests/ui/methods/probe-error-on-infinite-deref.rs | 1 + .../methods/probe-error-on-infinite-deref.stderr | 8 +- tests/ui/methods/untrimmed-path-type.stderr | 2 +- .../defaulted-never-note.fallback.stderr | 2 +- tests/ui/never_type/defaulted-never-note.rs | 2 +- .../diverging-fallback-no-leak.fallback.stderr | 2 +- tests/ui/recursion/issue-23122-2.rs | 1 + tests/ui/recursion/issue-23122-2.stderr | 8 +- .../issue-38591-non-regular-dropck-recursion.rs | 1 + ...issue-38591-non-regular-dropck-recursion.stderr | 6 +- tests/ui/recursion/issue-83150.rs | 2 +- tests/ui/recursion/issue-83150.stderr | 6 +- .../arbitrary_self_type_infinite_recursion.stderr | 2 +- ..._self_types_not_allow_call_with_no_deref.stderr | 4 +- .../arbitrary_self_types_pin_needing_borrow.rs | 2 +- .../arbitrary_self_types_pin_needing_borrow.stderr | 2 +- tests/ui/simd/libm_no_std_cant_float.stderr | 12 +- tests/ui/suggestions/enum-method-probe.fixed | 12 +- tests/ui/suggestions/enum-method-probe.rs | 12 +- tests/ui/suggestions/enum-method-probe.stderr | 12 +- tests/ui/suggestions/field-has-method.rs | 2 +- tests/ui/suggestions/field-has-method.stderr | 2 +- tests/ui/suggestions/inner_type.fixed | 10 +- tests/ui/suggestions/inner_type.rs | 10 +- tests/ui/suggestions/inner_type.stderr | 10 +- tests/ui/suggestions/inner_type2.rs | 4 +- tests/ui/suggestions/inner_type2.stderr | 4 +- tests/ui/traits/issue-91949-hangs-on-recursion.rs | 2 +- .../traits/issue-91949-hangs-on-recursion.stderr | 4 +- 68 files changed, 397 insertions(+), 339 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 96c7ba6ed27..5a5563c7bb2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1382,6 +1382,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { &mut self.long_ty_path } + pub fn with_long_ty_path(mut self, long_ty_path: Option) -> Self { + self.long_ty_path = long_ty_path; + self + } + /// 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/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 7e2bfa9f920..1675aecd2b8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1135,9 +1135,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } } else { + let trait_ = + tcx.short_string(bound.print_only_trait_path(), err.long_ty_path()); err.note(format!( - "associated {assoc_kind_str} `{assoc_ident}` could derive from `{}`", - bound.print_only_trait_path(), + "associated {assoc_kind_str} `{assoc_ident}` could derive from `{trait_}`", )); } } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index bac4d70103c..1ed0756fdd6 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -159,7 +159,7 @@ hir_typeck_lossy_provenance_ptr2int = .suggestion = use `.addr()` to obtain the address of a pointer .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead -hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` +hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty}` hir_typeck_naked_asm_outside_naked_fn = the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]` @@ -184,7 +184,7 @@ hir_typeck_never_type_fallback_flowing_into_unsafe_path = never type fallback af hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access .help = specify the type explicitly -hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> +hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty}`{$trait_missing_method -> [true] {""} *[other] {" "}in the current scope } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index a8bb6956f10..d15d092b7d3 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -200,11 +200,11 @@ pub(crate) enum ExplicitDestructorCallSugg { #[derive(Diagnostic)] #[diag(hir_typeck_missing_parentheses_in_range, code = E0689)] -pub(crate) struct MissingParenthesesInRange { +pub(crate) struct MissingParenthesesInRange<'tcx> { #[primary_span] #[label(hir_typeck_missing_parentheses_in_range)] pub span: Span, - pub ty_str: String, + pub ty: Ty<'tcx>, pub method_name: String, #[subdiagnostic] pub add_missing_parentheses: Option, @@ -828,13 +828,13 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> { #[derive(Diagnostic)] #[diag(hir_typeck_no_associated_item, code = E0599)] -pub(crate) struct NoAssociatedItem { +pub(crate) struct NoAssociatedItem<'tcx> { #[primary_span] pub span: Span, pub item_kind: &'static str, pub item_ident: Ident, pub ty_prefix: Cow<'static, str>, - pub ty_str: String, + pub ty: Ty<'tcx>, pub trait_missing_method: bool, } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 0c0cc752b01..7848d9323c5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -376,16 +376,20 @@ 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; + fn suggest_missing_writer( + &self, + rcvr_ty: Ty<'tcx>, + rcvr_expr: &hir::Expr<'tcx>, + mut long_ty_path: Option, + ) -> Diag<'_> { let mut err = struct_span_code_err!( self.dcx(), rcvr_expr.span, E0599, "cannot write into `{}`", - self.tcx.short_string(rcvr_ty, &mut file), + self.tcx.short_string(rcvr_ty, &mut long_ty_path), ); - *err.long_ty_path() = file; + *err.long_ty_path() = long_ty_path; err.span_note( rcvr_expr.span, "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", @@ -403,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, self_source: SelfSource<'tcx>, method_name: Ident, - ty_str_reported: &str, + ty: Ty<'tcx>, err: &mut Diag<'_>, ) { #[derive(Debug)] @@ -478,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If the shadowed binding has an itializer expression, - // use the initializer expression'ty to try to find the method again. + // use the initializer expression's ty to try to find the method again. // For example like: `let mut x = Vec::new();`, // `Vec::new()` is the itializer expression. if let Some(self_ty) = self.fcx.node_ty_opt(binding.init_hir_id) @@ -566,17 +570,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut span = MultiSpan::from_span(sugg_let.span); span.push_span_label(sugg_let.span, format!("`{rcvr_name}` of type `{self_ty}` that has method `{method_name}` defined earlier here")); + + let ty = self.tcx.short_string(ty, err.long_ty_path()); span.push_span_label( self.tcx.hir_span(recv_id), - format!( - "earlier `{rcvr_name}` shadowed here with type `{ty_str_reported}`" - ), + format!("earlier `{rcvr_name}` shadowed here with type `{ty}`"), ); err.span_note( span, format!( "there's an earlier shadowed binding `{rcvr_name}` of type `{self_ty}` \ - that has method `{method_name}` available" + that has method `{method_name}` available" ), ); } @@ -602,15 +606,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); let mut ty_file = None; - let (ty_str, short_ty_str) = - if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() { - (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string())) - } else { - ( - tcx.short_string(rcvr_ty, &mut ty_file), - with_forced_trimmed_paths!(rcvr_ty.to_string()), - ) - }; let is_method = mode == Mode::MethodCall; let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; let similar_candidate = no_match_data.similar_candidate; @@ -629,15 +624,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - if let Err(guar) = self.report_failed_method_call_on_range_end( - tcx, - rcvr_ty, - source, - span, - item_ident, - &short_ty_str, - &mut ty_file, - ) { + if let Err(guar) = + self.report_failed_method_call_on_range_end(tcx, rcvr_ty, source, span, item_ident) + { return guar; } if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( @@ -647,44 +636,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, item_kind, item_ident, - &short_ty_str, &mut ty_file, ) { return guar; } span = item_ident.span; - // Don't show generic arguments when the method can't be found in any implementation (#81576). - let mut ty_str_reported = ty_str.clone(); - if let ty::Adt(_, generics) = rcvr_ty.kind() { - if generics.len() > 0 { - let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors(); - let candidate_found = autoderef.any(|(ty, _)| { - if let ty::Adt(adt_def, _) = ty.kind() { - self.tcx - .inherent_impls(adt_def.did()) - .into_iter() - .any(|def_id| self.associated_value(*def_id, item_ident).is_some()) - } else { - false - } - }); - let has_deref = autoderef.step_count() > 0; - if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() { - if let Some((path_string, _)) = ty_str.split_once('<') { - ty_str_reported = path_string.to_string(); - } - } - } - } - let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.is_some_and(|def_id| { tcx.is_diagnostic_item(sym::write_macro, def_id) || tcx.is_diagnostic_item(sym::writeln_macro, def_id) }) && item_ident.name == sym::write_fmt; let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { - self.suggest_missing_writer(rcvr_ty, rcvr_expr) + self.suggest_missing_writer(rcvr_ty, rcvr_expr, ty_file) } else { + // Don't show expanded generic arguments when the method can't be found in any + // implementation (#81576). + let mut ty = rcvr_ty; + if let ty::Adt(def, generics) = rcvr_ty.kind() { + if generics.len() > 0 { + let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors(); + let candidate_found = autoderef.any(|(ty, _)| { + if let ty::Adt(adt_def, _) = ty.kind() { + self.tcx + .inherent_impls(adt_def.did()) + .into_iter() + .any(|def_id| self.associated_value(*def_id, item_ident).is_some()) + } else { + false + } + }); + let has_deref = autoderef.step_count() > 0; + if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() { + ty = self.tcx.at(span).type_of(def.did()).instantiate_identity(); + } + } + } + let mut err = self.dcx().create_err(NoAssociatedItem { span, item_kind, @@ -695,16 +682,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { rcvr_ty.prefix_string(self.tcx) }, - ty_str: ty_str_reported.clone(), + ty, trait_missing_method, }); if is_method { self.suggest_use_shadowed_binding_with_method( - source, - item_ident, - &ty_str_reported, - &mut err, + source, item_ident, rcvr_ty, &mut err, ); } @@ -734,6 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err }; + if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); } @@ -750,6 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if tcx.ty_is_opaque_future(rcvr_ty) && item_ident.name == sym::poll { + let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path()); err.help(format!( "method `poll` found on `Pin<&mut {ty_str}>`, \ see documentation for `std::pin::Pin`" @@ -1339,7 +1325,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let OnUnimplementedNote { message, label, notes, .. } = self .err_ctxt() - .on_unimplemented_note(trait_ref, &obligation, &mut ty_file); + .on_unimplemented_note(trait_ref, &obligation, err.long_ty_path()); (message, label, notes) }) .unwrap() @@ -1347,6 +1333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (None, None, Vec::new()) }; let primary_message = primary_message.unwrap_or_else(|| { + let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path()); format!( "the {item_kind} `{item_ident}` exists for {actual_prefix} `{ty_str}`, \ but its trait bounds were not satisfied" @@ -1409,6 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut find_candidate_for_method = false; let mut label_span_not_found = |err: &mut Diag<'_>| { + let ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path()); if unsatisfied_predicates.is_empty() { err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); let is_string_or_ref_str = match rcvr_ty.kind() { @@ -2520,8 +2508,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: SelfSource<'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) { @@ -2583,18 +2569,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - let mut err = self.dcx().create_err(errors::MissingParenthesesInRange { + return Err(self.dcx().emit_err(errors::MissingParenthesesInRange { span, - ty_str: ty_str.to_string(), + ty: actual, method_name: item_name.as_str().to_string(), add_missing_parentheses: Some(errors::AddMissingParenthesesInRange { func_name: item_name.name.as_str().to_string(), left: range_span.shrink_to_lo(), right: range_span.shrink_to_hi(), }), - }); - *err.long_ty_path() = long_ty_path.take(); - return Err(err.emit()); + })); } } } @@ -2610,7 +2594,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, item_kind: &str, item_name: Ident, - ty_str: &str, long_ty_path: &mut Option, ) -> Result<(), ErrorGuaranteed> { let found_candidate = all_traits(self.tcx) @@ -2643,14 +2626,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !actual.has_concrete_skeleton() && let SelfSource::MethodCall(expr) = source { + let ty_str = self.tcx.short_string(actual, long_ty_path); let mut err = struct_span_code_err!( self.dcx(), span, E0689, - "can't call {} `{}` on ambiguous numeric type `{}`", - item_kind, - item_name, - ty_str + "can't call {item_kind} `{item_name}` on ambiguous numeric type `{ty_str}`" ); *err.long_ty_path() = long_ty_path.take(); let concrete_type = if actual.is_integral() { "i32" } else { "f32" }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index b381d62be47..67244e767cb 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2987,7 +2987,7 @@ impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> { } } -#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] +#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] pub struct TraitPredPrintModifiersAndPath<'tcx>(ty::TraitPredicate<'tcx>); impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> { diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 8232da4df43..fcb25025087 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -171,8 +171,6 @@ trait_selection_fps_remove_ref = consider removing the reference trait_selection_fps_use_ref = consider using a reference trait_selection_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime -trait_selection_full_type_written = the full type name has been written to '{$path}' - trait_selection_ignored_diagnostic_option = `{$option_name}` is ignored due to previous definition of `{$option_name}` .other_label = `{$option_name}` is first declared here .label = `{$option_name}` is already declared here 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 ed8229154a9..1c890821b1d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1930,7 +1930,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &self, trace: &TypeTrace<'tcx>, terr: TypeError<'tcx>, - path: &mut Option, + long_ty_path: &mut Option, ) -> Vec { let mut suggestions = Vec::new(); let span = trace.cause.span; @@ -2009,7 +2009,8 @@ 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, path) + && let Some((expected_ty, found_ty)) = + self.values_str(trace.values, &trace.cause, long_ty_path) { suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { found: found_ty.content(), @@ -2139,11 +2140,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &self, values: ValuePairs<'tcx>, cause: &ObligationCause<'tcx>, - file: &mut Option, + long_ty_path: &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, file), + ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found, long_ty_path), 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), @@ -2183,7 +2184,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn expected_found_str_term( &self, exp_found: ty::error::ExpectedFound>, - path: &mut Option, + long_ty_path: &mut Option, ) -> Option<(DiagStyledString, DiagStyledString)> { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { @@ -2200,11 +2201,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let exp_s = exp.content(); let fnd_s = fnd.content(); if exp_s.len() > len { - let exp_s = self.tcx.short_string(expected, path); + let exp_s = self.tcx.short_string(expected, long_ty_path); exp = DiagStyledString::highlighted(exp_s); } if fnd_s.len() > len { - let fnd_s = self.tcx.short_string(found, path); + let fnd_s = self.tcx.short_string(found, long_ty_path); fnd = DiagStyledString::highlighted(fnd_s); } (exp, fnd) 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 966f117a1bf..ec2287ed516 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 @@ -436,8 +436,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer_subdiags, multi_suggestions, bad_label, - was_written: false, - path: Default::default(), }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -447,8 +445,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer_subdiags, multi_suggestions, bad_label, - was_written: false, - path: Default::default(), }), TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn { span, @@ -458,8 +454,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer_subdiags, multi_suggestions, bad_label, - was_written: false, - path: Default::default(), }), } } @@ -496,7 +490,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return self.bad_inference_failure_err(failure_span, arg_data, error_code); }; - let (source_kind, name, path) = kind.ty_localized_msg(self); + let (source_kind, name, long_ty_path) = kind.ty_localized_msg(self); let failure_span = if should_label_span && !failure_span.overlaps(span) { Some(failure_span) } else { @@ -628,7 +622,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } } - match error_code { + let mut err = match error_code { TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired { span, source_kind, @@ -637,8 +631,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer_subdiags, multi_suggestions, bad_label: None, - was_written: path.is_some(), - path: path.unwrap_or_default(), }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -648,8 +640,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer_subdiags, multi_suggestions, bad_label: None, - was_written: path.is_some(), - path: path.unwrap_or_default(), }), TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn { span, @@ -659,10 +649,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { infer_subdiags, multi_suggestions, bad_label: None, - was_written: path.is_some(), - path: path.unwrap_or_default(), }), - } + }; + *err.long_ty_path() = long_ty_path; + err } } @@ -726,22 +716,24 @@ impl<'tcx> InferSource<'tcx> { impl<'tcx> InferSourceKind<'tcx> { fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option) { - let mut path = None; + let mut long_ty_path = None; match *self { InferSourceKind::LetBinding { ty, .. } | InferSourceKind::ClosureArg { ty, .. } | InferSourceKind::ClosureReturn { ty, .. } => { if ty.is_closure() { - ("closure", closure_as_fn_str(infcx, ty), path) + ("closure", closure_as_fn_str(infcx, ty), long_ty_path) } else if !ty.is_ty_or_numeric_infer() { - ("normal", infcx.tcx.short_string(ty, &mut path), path) + ("normal", infcx.tcx.short_string(ty, &mut long_ty_path), long_ty_path) } else { - ("other", String::new(), path) + ("other", String::new(), long_ty_path) } } // FIXME: We should be able to add some additional info here. InferSourceKind::GenericArg { .. } - | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new(), path), + | InferSourceKind::FullyQualifiedMethodCall { .. } => { + ("other", String::new(), long_ty_path) + } } } } 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 cdf1402252a..af912227ce4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -169,7 +169,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; + let mut long_ty_path = None; debug!(?predicate, obligation.cause.code = ?obligation.cause.code()); @@ -211,19 +211,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.as_lang_item(trait_pred.def_id()), Some(LangItem::Sized | LangItem::MetaSized) ) { - match self.tainted_by_errors() { - None => { - let err = self.emit_inference_failure_err( + return match self.tainted_by_errors() { + None => self + .emit_inference_failure_err( obligation.cause.body_id, span, trait_pred.self_ty().skip_binder().into(), TypeAnnotationNeeded::E0282, false, - ); - return err.emit(); - } - Some(e) => return e, - } + ) + .emit(), + Some(e) => e, + }; } // Typically, this ambiguity should only happen if @@ -260,8 +259,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span, E0283, "type annotations needed: cannot satisfy `{}`", - self.tcx.short_string(predicate, &mut file), + self.tcx.short_string(predicate, &mut long_ty_path), ) + .with_long_ty_path(long_ty_path) }; let mut ambiguities = compute_applicable_impls_for_diagnostics( @@ -307,7 +307,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.cancel(); return e; } - let pred = self.tcx.short_string(predicate, &mut file); + let pred = self.tcx.short_string(predicate, &mut err.long_ty_path()); err.note(format!("cannot satisfy `{pred}`")); let impl_candidates = self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap()); @@ -512,6 +512,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { true, ) } + ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { if let Err(e) = predicate.error_reported() { return e; @@ -536,7 +537,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .filter_map(ty::GenericArg::as_term) .chain([data.term]) .find(|g| g.has_non_region_infer()); - let predicate = self.tcx.short_string(predicate, &mut file); + let predicate = self.tcx.short_string(predicate, &mut long_ty_path); if let Some(term) = term { self.emit_inference_failure_err( obligation.cause.body_id, @@ -546,6 +547,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { true, ) .with_note(format!("cannot satisfy `{predicate}`")) + .with_long_ty_path(long_ty_path) } else { // If we can't find a generic parameter, just print a generic error struct_span_code_err!( @@ -555,6 +557,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "type annotations needed: cannot satisfy `{predicate}`", ) .with_span_label(span, format!("cannot satisfy `{predicate}`")) + .with_long_ty_path(long_ty_path) } } @@ -568,17 +571,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let term = data.walk().filter_map(ty::GenericArg::as_term).find(|term| term.is_infer()); if let Some(term) = term { - let err = self.emit_inference_failure_err( + self.emit_inference_failure_err( obligation.cause.body_id, span, term, TypeAnnotationNeeded::E0284, true, - ); - err + ) } else { // If we can't find a generic parameter, just print a generic error - let predicate = self.tcx.short_string(predicate, &mut file); + let predicate = self.tcx.short_string(predicate, &mut long_ty_path); struct_span_code_err!( self.dcx(), span, @@ -586,6 +588,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "type annotations needed: cannot satisfy `{predicate}`", ) .with_span_label(span, format!("cannot satisfy `{predicate}`")) + .with_long_ty_path(long_ty_path) } } @@ -597,13 +600,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { TypeAnnotationNeeded::E0284, true, ), + ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) if term.is_infer() => { if let Some(e) = self.tainted_by_errors() { return e; } - let alias = self.tcx.short_string(alias, &mut file); + let alias = self.tcx.short_string(alias, &mut long_ty_path); struct_span_code_err!( self.dcx(), span, @@ -611,37 +615,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "type annotations needed: cannot normalize `{alias}`", ) .with_span_label(span, format!("cannot normalize `{alias}`")) + .with_long_ty_path(long_ty_path) } + ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(sym)) => { if let Some(e) = self.tainted_by_errors() { return e; } - let mut err; - if self.tcx.features().staged_api() { - err = self.dcx().struct_span_err( + self.dcx().struct_span_err( span, format!("unstable feature `{sym}` is used without being enabled."), - ); - - err.help(format!("The feature can be enabled by marking the current item with `#[unstable_feature_bound({sym})]`")); + ).with_help(format!("The feature can be enabled by marking the current item with `#[unstable_feature_bound({sym})]`")) } else { - err = feature_err_unstable_feature_bound( + feature_err_unstable_feature_bound( &self.tcx.sess, sym, span, format!("use of unstable library feature `{sym}`"), - ); + ) } - err } _ => { if let Some(e) = self.tainted_by_errors() { return e; } - let predicate = self.tcx.short_string(predicate, &mut file); + let predicate = self.tcx.short_string(predicate, &mut long_ty_path); struct_span_code_err!( self.dcx(), span, @@ -649,9 +650,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "type annotations needed: cannot satisfy `{predicate}`", ) .with_span_label(span, format!("cannot satisfy `{predicate}`")) + .with_long_ty_path(long_ty_path) } }; - *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 a9e346a5cdb..62859329de3 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 @@ -208,16 +208,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { performs a conversion on the error value \ using the `From` trait"; let (message, notes, append_const_msg) = if is_try_conversion { + let ty = self.tcx.short_string( + main_trait_predicate.skip_binder().self_ty(), + &mut long_ty_file, + ); // We have a `-> Result<_, E1>` and `gives_E2()?`. ( - Some(format!( - "`?` couldn't convert the error to `{}`", - main_trait_predicate.skip_binder().self_ty(), - )), + Some(format!("`?` couldn't convert the error to `{ty}`")), vec![question_mark_message.to_owned()], Some(AppendConstMessage::Default), ) } else if is_question_mark { + let main_trait_predicate = + self.tcx.short_string(main_trait_predicate, &mut long_ty_file); // Similar to the case above, but in this case the conversion is for a // trait object: `-> Result<_, Box` and `gives_E()?` when // `E: Error` isn't met. @@ -233,7 +236,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (message, notes, append_const_msg) }; - let err_msg = self.get_standard_error_message( + let default_err_msg = || self.get_standard_error_message( main_trait_predicate, message, None, @@ -258,7 +261,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } GetSafeTransmuteErrorAndReason::Default => { - (err_msg, None) + (default_err_msg(), None) } GetSafeTransmuteErrorAndReason::Error { err_msg, @@ -266,7 +269,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } => (err_msg, safe_transmute_explanation), } } else { - (err_msg, None) + (default_err_msg(), None) }; let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); @@ -279,15 +282,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some(ret_span) = self.return_type_span(&obligation) { if is_try_conversion { + let ty = self.tcx.short_string( + main_trait_predicate.skip_binder().self_ty(), + err.long_ty_path(), + ); err.span_label( ret_span, - format!( - "expected `{}` because of this", - main_trait_predicate.skip_binder().self_ty() - ), + format!("expected `{ty}` because of this"), ); } else if is_question_mark { - err.span_label(ret_span, format!("required `{main_trait_predicate}` because of this")); + let main_trait_predicate = + self.tcx.short_string(main_trait_predicate, err.long_ty_path()); + err.span_label( + ret_span, + format!("required `{main_trait_predicate}` because of this"), + ); } } @@ -303,6 +312,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &obligation, leaf_trait_predicate, pre_message, + err.long_ty_path(), ); self.check_for_binding_assigned_block_without_tail_expression( @@ -414,11 +424,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { vec![(span.shrink_to_hi(), format!(" as {}", cand.self_ty()))] }; + let trait_ = self.tcx.short_string(cand.print_trait_sugared(), err.long_ty_path()); + let ty = self.tcx.short_string(cand.self_ty(), err.long_ty_path()); err.multipart_suggestion( format!( - "the trait `{}` is implemented for fn pointer `{}`, try casting using `as`", - cand.print_trait_sugared(), - cand.self_ty(), + "the trait `{trait_}` is implemented for fn pointer \ + `{ty}`, try casting using `as`", ), suggestion, Applicability::MaybeIncorrect, @@ -522,7 +533,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { \ for more information)", ); - err.help("did you intend to use the type `()` here instead?"); + err.help("you might have intended to use the type `()` here instead"); } } @@ -722,10 +733,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty } => { + let expected_ty_str = self.tcx.short_string(expected_ty, &mut long_ty_file); + let ct_str = self.tcx.short_string(ct, &mut long_ty_file); let mut diag = self.dcx().struct_span_err( span, - format!("the constant `{ct}` is not of type `{expected_ty}`"), + format!("the constant `{ct_str}` is not of type `{expected_ty_str}`"), ); + diag.long_ty_path = long_ty_file; self.note_type_err( &mut diag, @@ -1118,9 +1132,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .must_apply_modulo_regions() { if !suggested { + let err_ty = self.tcx.short_string(err_ty, err.long_ty_path()); err.span_label(span, format!("this has type `Result<_, {err_ty}>`")); } } else { + let err_ty = self.tcx.short_string(err_ty, err.long_ty_path()); err.span_label( span, format!( @@ -1156,12 +1172,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } (ty::Adt(def, _), None) if def.did().is_local() => { + let trait_path = self.tcx.short_string( + trait_pred.skip_binder().trait_ref.print_only_trait_path(), + err.long_ty_path(), + ); err.span_note( self.tcx.def_span(def.did()), - format!( - "`{self_ty}` needs to implement `{}`", - trait_pred.skip_binder().trait_ref.print_only_trait_path(), - ), + format!("`{self_ty}` needs to implement `{trait_path}`"), ); } (ty::Adt(def, _), Some(ty)) if def.did().is_local() => { @@ -1195,13 +1212,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { bug!() }; + let mut file = None; + let ty_str = self.tcx.short_string(ty, &mut file); let mut diag = match ty.kind() { ty::Float(_) => { struct_span_code_err!( self.dcx(), span, E0741, - "`{ty}` is forbidden as the type of a const generic parameter", + "`{ty_str}` is forbidden as the type of a const generic parameter", ) } ty::FnPtr(..) => { @@ -1226,7 +1245,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.dcx(), span, E0741, - "`{ty}` must implement `ConstParamTy` to be used as the type of a const generic parameter", + "`{ty_str}` must implement `ConstParamTy` to be used as the type of a const generic parameter", ); // Only suggest derive if this isn't a derived obligation, // and the struct is local. @@ -1258,21 +1277,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.dcx(), span, E0741, - "`{ty}` can't be used as a const parameter type", + "`{ty_str}` can't be used as a const parameter type", ) } }; + diag.long_ty_path = file; let mut code = obligation.cause.code(); let mut pred = obligation.predicate.as_trait_clause(); while let Some((next_code, next_pred)) = code.parent_with_predicate() { if let Some(pred) = pred { self.enter_forall(pred, |pred| { - diag.note(format!( - "`{}` must implement `{}`, but it does not", - pred.self_ty(), - pred.print_modifiers_and_trait_path() - )); + let ty = self.tcx.short_string(pred.self_ty(), diag.long_ty_path()); + let trait_path = self + .tcx + .short_string(pred.print_modifiers_and_trait_path(), diag.long_ty_path()); + diag.note(format!("`{ty}` must implement `{trait_path}`, but it does not")); }) } code = next_code; @@ -1584,7 +1604,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, + long_ty_path: &mut Option, ) -> Option<(String, Span, Option)> { let trait_def_id = projection_term.trait_def_id(self.tcx); let self_ty = projection_term.self_ty(); @@ -1624,17 +1644,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), - _ => self.tcx.short_string(self_ty, file), + _ => self.tcx.short_string(self_ty, long_ty_path), }; + let expected_ty = self.tcx.short_string(expected_ty, long_ty_path); + let normalized_ty = self.tcx.short_string(normalized_ty, long_ty_path); Some((format!( "expected `{item}` to return `{expected_ty}`, but it returns `{normalized_ty}`", ), span, closure_span)) } else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) { + let self_ty = self.tcx.short_string(self_ty, long_ty_path); + let expected_ty = self.tcx.short_string(expected_ty, long_ty_path); + let normalized_ty = self.tcx.short_string(normalized_ty, long_ty_path); Some((format!( "expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \ resolves to `{normalized_ty}`" ), span, None)) } else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) { + let self_ty = self.tcx.short_string(self_ty, long_ty_path); + let expected_ty = self.tcx.short_string(expected_ty, long_ty_path); + let normalized_ty = self.tcx.short_string(normalized_ty, long_ty_path); Some((format!( "expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it \ yields `{normalized_ty}`" @@ -2097,12 +2125,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let [TypeError::Sorts(exp_found)] = &terrs[..] { let exp_found = self.resolve_vars_if_possible(*exp_found); + let expected = + self.tcx.short_string(exp_found.expected, err.long_ty_path()); + let found = self.tcx.short_string(exp_found.found, err.long_ty_path()); err.highlighted_help(vec![ StringPart::normal("for that trait implementation, "), StringPart::normal("expected `"), - StringPart::highlighted(exp_found.expected.to_string()), + StringPart::highlighted(expected), StringPart::normal("`, found `"), - StringPart::highlighted(exp_found.found.to_string()), + StringPart::highlighted(found), StringPart::normal("`"), ]); self.suggest_function_pointers_impl(None, &exp_found, err); @@ -2135,11 +2166,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (ty::FnPtr(..), _) => (" implemented for fn pointer `", ""), _ => (" implemented for `", ""), }; + let trait_ = self.tcx.short_string(cand.print_trait_sugared(), err.long_ty_path()); + let self_ty = self.tcx.short_string(cand.self_ty(), err.long_ty_path()); err.highlighted_help(vec![ - StringPart::normal(format!("the trait `{}` ", cand.print_trait_sugared())), + StringPart::normal(format!("the trait `{trait_}` ",)), StringPart::highlighted("is"), StringPart::normal(desc), - StringPart::highlighted(cand.self_ty().to_string()), + StringPart::highlighted(self_ty), StringPart::normal("`"), StringPart::normal(mention_castable), ]); @@ -2159,9 +2192,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .into_iter() .map(|c| { if all_traits_equal { - format!("\n {}", c.self_ty()) + format!("\n {}", self.tcx.short_string(c.self_ty(), err.long_ty_path())) } else { - format!("\n `{}` implements `{}`", c.self_ty(), c.print_only_trait_path()) + format!( + "\n `{}` implements `{}`", + self.tcx.short_string(c.self_ty(), err.long_ty_path()), + self.tcx.short_string(c.print_only_trait_path(), err.long_ty_path()), + ) } }) .collect(); @@ -2477,7 +2514,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { predicate_constness: Option, append_const_msg: Option, post_message: String, - long_ty_file: &mut Option, + long_ty_path: &mut Option, ) -> String { message .and_then(|cannot_do_this| { @@ -2503,7 +2540,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { "the trait bound `{}` is not satisfied{post_message}", self.tcx.short_string( trait_predicate.print_with_bound_constness(predicate_constness), - long_ty_file, + long_ty_path, ), ) }) @@ -2608,8 +2645,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { dst_min_align, } => { format!( - "the minimum alignment of `{src}` ({src_min_align}) should \ - be greater than that of `{dst}` ({dst_min_align})" + "the minimum alignment of `{src}` ({src_min_align}) should be \ + greater than that of `{dst}` ({dst_min_align})" ) } rustc_transmute::Reason::DstIsMoreUnique => { 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 5765dfd891d..bb5c6469f34 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 @@ -99,7 +99,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, trait_pred: ty::PolyTraitPredicate<'tcx>, obligation: &PredicateObligation<'tcx>, - long_ty_file: &mut Option, + long_ty_path: &mut Option, ) -> OnUnimplementedNote { if trait_pred.polarity() != ty::PredicatePolarity::Positive { return OnUnimplementedNote::default(); @@ -281,7 +281,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { if let Some(ty) = trait_pred.trait_ref.args[param.index as usize].as_type() { - self.tcx.short_string(ty, long_ty_file) + self.tcx.short_string(ty, long_ty_path) } else { trait_pred.trait_ref.args[param.index as usize].to_string() } 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 718cff6d135..374e1f67930 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3,6 +3,7 @@ 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; @@ -1369,6 +1370,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); let self_ty_str = self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); + let trait_path = self + .tcx + .short_string(old_pred.print_modifiers_and_trait_path(), err.long_ty_path()); + if has_custom_message { err.note(msg); } else { @@ -1376,10 +1381,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } err.span_label( span, - format!( - "the trait `{}` is not implemented for `{self_ty_str}`", - old_pred.print_modifiers_and_trait_path() - ), + format!("the trait `{trait_path}` is not implemented for `{self_ty_str}`"), ); }; @@ -3333,17 +3335,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { tcx.async_fn_trait_kind_from_def_id(data.parent_trait_pred.def_id()).is_some(); if !is_upvar_tys_infer_tuple && !is_builtin_async_fn_trait { - let ty_str = tcx.short_string(ty, err.long_ty_path()); - let msg = format!("required because it appears within the type `{ty_str}`"); + let mut msg = || { + let ty_str = tcx.short_string(ty, err.long_ty_path()); + format!("required because it appears within the type `{ty_str}`") + }; match ty.kind() { - ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) { - Some(ident) => { - err.span_note(ident.span, msg); - } - None => { - err.note(msg); + ty::Adt(def, _) => { + let msg = msg(); + match tcx.opt_item_ident(def.did()) { + Some(ident) => { + err.span_note(ident.span, msg); + } + None => { + err.note(msg); + } } - }, + } ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { // If the previous type is async fn, this is the future generated by the body of an async function. // Avoid printing it twice (it was already printed in the `ty::Coroutine` arm below). @@ -3363,6 +3370,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { // See comment above; skip printing twice. } else { + let msg = msg(); err.span_note(tcx.def_span(def_id), msg); } } @@ -3392,6 +3400,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"); } _ => { + let msg = msg(); err.note(msg); } }; @@ -3441,7 +3450,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let self_ty_str = 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 trait_name = tcx.short_string( + parent_trait_pred.print_modifiers_and_trait_path(), + err.long_ty_path(), + ); let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`"); let mut is_auto_trait = false; match tcx.hir_get_if_local(data.impl_or_alias_def_id) { @@ -3539,10 +3551,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { 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() - )); + let trait_path = tcx.short_string( + parent_trait_pred.print_modifiers_and_trait_path(), + err.long_ty_path(), + ); + err.note(format!("required for `{self_ty}` to implement `{trait_path}`")); } // #74711: avoid a stack overflow ensure_sufficient_stack(|| { @@ -3558,15 +3571,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }); } ObligationCauseCode::ImplDerivedHost(ref data) => { - let self_ty = - self.resolve_vars_if_possible(data.derived.parent_host_pred.self_ty()); - let msg = format!( - "required for `{self_ty}` to implement `{} {}`", - data.derived.parent_host_pred.skip_binder().constness, + let self_ty = tcx.short_string( + self.resolve_vars_if_possible(data.derived.parent_host_pred.self_ty()), + err.long_ty_path(), + ); + let trait_path = tcx.short_string( data.derived .parent_host_pred .map_bound(|pred| pred.trait_ref) .print_only_trait_path(), + err.long_ty_path(), + ); + let msg = format!( + "required for `{self_ty}` to implement `{} {trait_path}`", + data.derived.parent_host_pred.skip_binder().constness, ); match tcx.hir_get_if_local(data.impl_def_id) { Some(Node::Item(hir::Item { @@ -5351,6 +5369,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>( obligation: &PredicateObligation<'tcx>, trait_predicate: ty::PolyTraitPredicate<'tcx>, pre_message: String, + long_ty_path: &mut Option, ) -> String { if let ObligationCauseCode::MainFunctionType = obligation.cause.code() { "consider using `()`, or a `Result`".to_owned() @@ -5369,7 +5388,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_string(trait_predicate.self_ty().skip_binder(), &mut None), + tcx.short_string(trait_predicate.self_ty().skip_binder(), long_ty_path), ) } else { // "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 7901d52dffb..af241099c01 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1,5 +1,3 @@ -use std::path::PathBuf; - use rustc_ast::Path; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::codes::*; @@ -224,9 +222,6 @@ pub struct AnnotationRequired<'a> { pub infer_subdiags: Vec>, #[subdiagnostic] pub multi_suggestions: Vec>, - #[note(trait_selection_full_type_written)] - pub was_written: bool, - pub path: PathBuf, } // Copy of `AnnotationRequired` for E0283 @@ -245,9 +240,6 @@ pub struct AmbiguousImpl<'a> { pub infer_subdiags: Vec>, #[subdiagnostic] pub multi_suggestions: Vec>, - #[note(trait_selection_full_type_written)] - pub was_written: bool, - pub path: PathBuf, } // Copy of `AnnotationRequired` for E0284 @@ -266,9 +258,6 @@ pub struct AmbiguousReturn<'a> { pub infer_subdiags: Vec>, #[subdiagnostic] pub multi_suggestions: Vec>, - #[note(trait_selection_full_type_written)] - pub was_written: bool, - pub path: PathBuf, } // Used when a better one isn't available diff --git a/tests/ui/attributes/rustc_confusables_std_cases.stderr b/tests/ui/attributes/rustc_confusables_std_cases.stderr index f2d9ebe2c0e..771c0c6dfe9 100644 --- a/tests/ui/attributes/rustc_confusables_std_cases.stderr +++ b/tests/ui/attributes/rustc_confusables_std_cases.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `push` found for struct `BTreeSet` in the current scope +error[E0599]: no method named `push` found for struct `BTreeSet` in the current scope --> $DIR/rustc_confusables_std_cases.rs:6:7 | LL | x.push(1); @@ -22,7 +22,7 @@ LL - x.push_back(1); LL + x.push(1); | -error[E0599]: no method named `push` found for struct `VecDeque` in the current scope +error[E0599]: no method named `push` found for struct `VecDeque` in the current scope --> $DIR/rustc_confusables_std_cases.rs:12:7 | LL | x.push(1); @@ -35,7 +35,7 @@ LL | let mut x = Vec::new(); | ^^^^^ `x` of type `Vec<_>` that has method `push` defined earlier here ... LL | let mut x = VecDeque::new(); - | ----- earlier `x` shadowed here with type `VecDeque` + | ----- earlier `x` shadowed here with type `VecDeque<_>` help: you might have meant to use `push_back` | LL | x.push_back(1); diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index a9045840173..3aafe05ba05 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,5 +1,6 @@ -//~ ERROR overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: FnMut(&'a _)` +//~ ERROR overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:14:41: 14:44}: FnMut(&'a _)` //@ build-fail +//@ compile-flags: -Zwrite-long-types-to-disk=yes #![recursion_limit = "32"] diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index 74d98fde285..1559de757e7 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,10 +1,12 @@ -error[E0275]: overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: FnMut(&'a _)` +error[E0275]: overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:14:41: 14:44}: FnMut(&'a _)` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` + = note: required for `Filter, {closure@overflow-during-mono.rs:14:41}>` to implement `Iterator` = note: 31 redundant requirements hidden - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `IntoIterator` + = note: required for `Filter, ...>, ...>, ...>, ...>` to implement `Iterator` + = note: required for `Filter, ...>, ...>, ...>, ...>` to implement `IntoIterator` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/overflow-during-mono.long-type-$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/confuse-field-and-method/issue-18343.stderr b/tests/ui/confuse-field-and-method/issue-18343.stderr index e50c971d837..9517617fe34 100644 --- a/tests/ui/confuse-field-and-method/issue-18343.stderr +++ b/tests/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/tests/ui/confuse-field-and-method/issue-2392.stderr b/tests/ui/confuse-field-and-method/issue-2392.stderr index 77930de44a7..e1ad24df80f 100644 --- a/tests/ui/confuse-field-and-method/issue-2392.stderr +++ b/tests/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the closure stored in `closure`, surround the field access with pa LL | (o_closure.closure)(); | + + -error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -65,7 +65,7 @@ help: to call the trait object stored in `boxed_closure`, surround the field acc LL | (boxed_closure.boxed_closure)(); | + + -error[E0599]: no method named `closure` found for struct `Obj` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | + + -error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr index 61e2a8f64dd..b0bfc720658 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr @@ -43,7 +43,7 @@ help: consider introducing lifetime `'a` here LL | impl<'a> Trait for Z { | ++++ -error[E0599]: no function or associated item named `new` found for struct `InvariantRef` in the current scope +error[E0599]: no function or associated item named `new` found for struct `InvariantRef<'a, T>` in the current scope --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41 | LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); diff --git a/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.rs b/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.rs index 17b76b6c832..2bb82a2ebf2 100644 --- a/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.rs +++ b/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.rs @@ -1,5 +1,6 @@ // Issue 22443: Reject code using non-regular types that would // otherwise cause dropck to loop infinitely. +//@ compile-flags: -Zwrite-long-types-to-disk=yes use std::marker::PhantomData; diff --git a/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr b/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr index 9360f4a98e9..330a40d925b 100644 --- a/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr +++ b/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr @@ -1,10 +1,12 @@ error[E0320]: overflow while adding drop-check rules for `FingerTree` - --> $DIR/dropck_no_diverge_on_nonregular_1.rs:24:9 + --> $DIR/dropck_no_diverge_on_nonregular_1.rs:25:9 | LL | let ft = | ^^ | - = note: overflowed on `FingerTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + = note: overflowed on `FingerTree>>>>>>>>>` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/dropck_no_diverge_on_nonregular_1.long-type-$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/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr index 2daf00f7804..f0d4de364fb 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr @@ -5,7 +5,7 @@ LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` | = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) - = help: did you intend to use the type `()` here instead? + = help: you might have intended to use the type `()` here instead error[E0277]: the trait bound `!: Default` is not satisfied --> $DIR/never-type-fallback-breaking.rs:37:5 @@ -14,7 +14,7 @@ LL | deserialize()?; | ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` | = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) - = help: did you intend to use the type `()` here instead? + = help: you might have intended to use the type `()` here instead note: required by a bound in `deserialize` --> $DIR/never-type-fallback-breaking.rs:33:23 | @@ -51,7 +51,7 @@ LL | takes_apit(|| Default::default())?; | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` | = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) - = help: did you intend to use the type `()` here instead? + = help: you might have intended to use the type `()` here instead error[E0277]: the trait bound `!: Default` is not satisfied --> $DIR/never-type-fallback-breaking.rs:76:17 @@ -62,7 +62,7 @@ LL | takes_apit2(mk()?); | required by a bound introduced by this call | = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) - = help: did you intend to use the type `()` here instead? + = help: you might have intended to use the type `()` here instead note: required by a bound in `takes_apit2` --> $DIR/never-type-fallback-breaking.rs:71:25 | diff --git a/tests/ui/error-codes/E0275.rs b/tests/ui/error-codes/E0275.rs index 28a9676f03e..98d4a3c01b9 100644 --- a/tests/ui/error-codes/E0275.rs +++ b/tests/ui/error-codes/E0275.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes trait Foo {} struct Bar(T); diff --git a/tests/ui/error-codes/E0275.stderr b/tests/ui/error-codes/E0275.stderr index 3b31c87320a..755404c1e16 100644 --- a/tests/ui/error-codes/E0275.stderr +++ b/tests/ui/error-codes/E0275.stderr @@ -1,17 +1,19 @@ error[E0275]: overflow evaluating the requirement `Bar>>>>>>: Foo` - --> $DIR/E0275.rs:5:33 + --> $DIR/E0275.rs:6:33 | LL | impl Foo for T where Bar: Foo {} | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) -note: required for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo` - --> $DIR/E0275.rs:5:9 +note: required for `Bar>>>>>>>>>>>>` to implement `Foo` + --> $DIR/E0275.rs:6:9 | LL | impl Foo for T where Bar: Foo {} | ^^^ ^ --- unsatisfied trait bound introduced here = note: 126 redundant requirements hidden = note: required for `Bar` to implement `Foo` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/E0275.long-type-$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/hrtb-doesnt-borrow-self-2.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs index d8a1f3fa69e..d2793afdd06 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs @@ -6,6 +6,8 @@ // This tests double-checks that we do not allow such behavior to leak // through again. +//@ compile-flags: -Zwrite-long-types-to-disk=yes + pub trait Stream { type Item; fn next(self) -> Option; diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr index 23b979e2ef0..91e65b2b073 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr @@ -1,5 +1,5 @@ -error[E0599]: the method `countx` exists for struct `Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>`, but its trait bounds were not satisfied - --> $DIR/hrtb-doesnt-borrow-self-2.rs:110:24 +error[E0599]: the method `countx` exists for struct `Filter &u64 {identity::}>, {closure@...}>`, but its trait bounds were not satisfied + --> $DIR/hrtb-doesnt-borrow-self-2.rs:112:24 | LL | pub struct Filter { | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt` @@ -8,19 +8,21 @@ LL | let count = filter.countx(); | ^^^^^^ method cannot be called due to unsatisfied trait bounds | note: the following trait bounds were not satisfied: - `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` - `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` - `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream` - --> $DIR/hrtb-doesnt-borrow-self-2.rs:96:50 + `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` + `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` + `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream` + --> $DIR/hrtb-doesnt-borrow-self-2.rs:98:50 | LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here = help: items from traits can only be used if the trait is implemented and in scope note: `StreamExt` defines an item `countx`, perhaps you need to implement it - --> $DIR/hrtb-doesnt-borrow-self-2.rs:64:1 + --> $DIR/hrtb-doesnt-borrow-self-2.rs:66:1 | LL | pub trait StreamExt | ^^^^^^^^^^^^^^^^^^^ + = note: the full name for the type has been written to '$TEST_BUILD_DIR/hrtb-doesnt-borrow-self-2.long-type-$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/impl-trait/auto-trait-leakage/auto-trait-leak2.rs b/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.rs index 09450089ada..ead81bf3374 100644 --- a/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.rs +++ b/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes use std::cell::Cell; use std::rc::Rc; diff --git a/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.stderr b/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.stderr index 52fa28145d6..ba76d9ba2b8 100644 --- a/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.stderr +++ b/tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak2.stderr @@ -1,5 +1,5 @@ error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:20:10 + --> $DIR/auto-trait-leak2.rs:21:10 | LL | fn before() -> impl Fn(i32) { | ------------ within this `impl Fn(i32)` @@ -11,23 +11,23 @@ LL | send(before()); | = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` note: required because it's used within this closure - --> $DIR/auto-trait-leak2.rs:10:5 + --> $DIR/auto-trait-leak2.rs:11:5 | LL | move |x| p.set(x) | ^^^^^^^^ note: required because it appears within the type `impl Fn(i32)` - --> $DIR/auto-trait-leak2.rs:5:16 + --> $DIR/auto-trait-leak2.rs:6:16 | LL | fn before() -> impl Fn(i32) { | ^^^^^^^^^^^^ note: required by a bound in `send` - --> $DIR/auto-trait-leak2.rs:13:12 + --> $DIR/auto-trait-leak2.rs:14:12 | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:25:10 + --> $DIR/auto-trait-leak2.rs:26:10 | LL | send(after()); | ---- ^^^^^^^ `Rc>` cannot be sent between threads safely @@ -39,17 +39,17 @@ LL | fn after() -> impl Fn(i32) { | = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` note: required because it's used within this closure - --> $DIR/auto-trait-leak2.rs:38:5 + --> $DIR/auto-trait-leak2.rs:39:5 | LL | move |x| p.set(x) | ^^^^^^^^ note: required because it appears within the type `impl Fn(i32)` - --> $DIR/auto-trait-leak2.rs:33:15 + --> $DIR/auto-trait-leak2.rs:34:15 | LL | fn after() -> impl Fn(i32) { | ^^^^^^^^^^^^ note: required by a bound in `send` - --> $DIR/auto-trait-leak2.rs:13:12 + --> $DIR/auto-trait-leak2.rs:14:12 | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` diff --git a/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.rs b/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.rs index 4fd15eea9e0..f1353f1805d 100644 --- a/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.rs +++ b/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes type A = (i32, i32, i32, i32); type B = (A, A, A, A); type C = (B, B, B, B); diff --git a/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr b/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr index 65fe2ffcb7f..5c4a1a75829 100644 --- a/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr +++ b/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr @@ -1,9 +1,11 @@ -error[E0282]: type annotations needed for `Result<_, ((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))>` - --> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:7:9 +error[E0282]: type annotations needed for `Result<_, (((..., ..., ..., ...), ..., ..., ...), ..., ..., ...)>` + --> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:8:9 | LL | let y = Err(x); | ^ ------ type must be known at this point | + = note: the full name for the type has been written to '$TEST_BUILD_DIR/really-long-type-in-let-binding-without-sufficient-type-info.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console help: consider giving `y` an explicit type, where the type for type parameter `T` is specified | LL | let y: Result = Err(x); diff --git a/tests/ui/interior-mutability/interior-mutability.rs b/tests/ui/interior-mutability/interior-mutability.rs index c704acc22af..7e4fe76852d 100644 --- a/tests/ui/interior-mutability/interior-mutability.rs +++ b/tests/ui/interior-mutability/interior-mutability.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes use std::cell::Cell; use std::panic::catch_unwind; fn main() { diff --git a/tests/ui/interior-mutability/interior-mutability.stderr b/tests/ui/interior-mutability/interior-mutability.stderr index cfc64445bf3..5a959d14c8a 100644 --- a/tests/ui/interior-mutability/interior-mutability.stderr +++ b/tests/ui/interior-mutability/interior-mutability.stderr @@ -1,5 +1,5 @@ error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/interior-mutability.rs:5:18 + --> $DIR/interior-mutability.rs:6:18 | LL | catch_unwind(|| { x.set(23); }); | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary @@ -11,7 +11,7 @@ note: required because it appears within the type `Cell` --> $SRC_DIR/core/src/cell.rs:LL:COL = note: required for `&Cell` to implement `UnwindSafe` note: required because it's used within this closure - --> $DIR/interior-mutability.rs:5:18 + --> $DIR/interior-mutability.rs:6:18 | LL | catch_unwind(|| { x.set(23); }); | ^^ diff --git a/tests/ui/issues/issue-41880.stderr b/tests/ui/issues/issue-41880.stderr index 1936c0aebd4..2f1ebee7ca5 100644 --- a/tests/ui/issues/issue-41880.stderr +++ b/tests/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for struct `Iterate` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/tests/ui/methods/call_method_unknown_referent.rs b/tests/ui/methods/call_method_unknown_referent.rs index b01e2d80f7f..b26ecc74175 100644 --- a/tests/ui/methods/call_method_unknown_referent.rs +++ b/tests/ui/methods/call_method_unknown_referent.rs @@ -44,5 +44,5 @@ fn main() { // our resolution logic needs to be able to call methods such as foo() // on the outer type even if the inner type is ambiguous. let _c = (ptr as SmartPtr<_>).read(); - //~^ ERROR no method named `read` found for struct `SmartPtr` + //~^ ERROR no method named `read` found for struct `SmartPtr` } diff --git a/tests/ui/methods/call_method_unknown_referent.stderr b/tests/ui/methods/call_method_unknown_referent.stderr index 748b02b52b5..5d6974a00c6 100644 --- a/tests/ui/methods/call_method_unknown_referent.stderr +++ b/tests/ui/methods/call_method_unknown_referent.stderr @@ -10,7 +10,7 @@ error[E0282]: type annotations needed LL | let _b = (rc as std::rc::Rc<_>).read(); | ^^^^ cannot infer type -error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope +error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope --> $DIR/call_method_unknown_referent.rs:46:35 | LL | struct SmartPtr(T); diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs index 4add93e808d..39b4ba983e4 100644 --- a/tests/ui/methods/inherent-bound-in-probe.rs +++ b/tests/ui/methods/inherent-bound-in-probe.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes // Fixes #110131 // // The issue is that we were constructing an `ImplDerived` cause code for the diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr index 77aed390c9a..b7751ca4714 100644 --- a/tests/ui/methods/inherent-bound-in-probe.stderr +++ b/tests/ui/methods/inherent-bound-in-probe.stderr @@ -1,5 +1,5 @@ error[E0277]: `Helper<'a, T>` is not an iterator - --> $DIR/inherent-bound-in-probe.rs:38:21 + --> $DIR/inherent-bound-in-probe.rs:39:21 | LL | type IntoIter = Helper<'a, T>; | ^^^^^^^^^^^^^ `Helper<'a, T>` is not an iterator @@ -9,14 +9,14 @@ note: required by a bound in `std::iter::IntoIterator::IntoIter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL error[E0275]: overflow evaluating the requirement `&_: IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:42:9 + --> $DIR/inherent-bound-in-probe.rs:43:9 | LL | Helper::new(&self.0) | ^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`) note: required for `&BitReaderWrapper<_>` to implement `IntoIterator` - --> $DIR/inherent-bound-in-probe.rs:32:13 + --> $DIR/inherent-bound-in-probe.rs:33:13 | LL | impl<'a, T> IntoIterator for &'a BitReaderWrapper | ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,15 +24,17 @@ LL | where LL | &'a T: IntoIterator, | ------------- unsatisfied trait bound introduced here = note: 126 redundant requirements hidden - = note: required for `&BitReaderWrapper>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `IntoIterator` + = note: required for `&BitReaderWrapper>>` to implement `IntoIterator` note: required by a bound in `Helper` - --> $DIR/inherent-bound-in-probe.rs:16:12 + --> $DIR/inherent-bound-in-probe.rs:17:12 | LL | struct Helper<'a, T> | ------ required by a bound in this struct LL | where LL | &'a T: IntoIterator, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Helper` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/inherent-bound-in-probe.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 2 previous errors diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index 8429c3aebac..75fabc27b0f 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -10,7 +10,7 @@ LL | let d = point_i32.distance(); = note: the method was found for - `Point` -error[E0599]: no method named `other` found for struct `Point` in the current scope +error[E0599]: no method named `other` found for struct `Point` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:84:23 | LL | struct Point { @@ -19,7 +19,7 @@ LL | struct Point { LL | let d = point_i32.other(); | ^^^^^ method not found in `Point` -error[E0599]: no method named `extend` found for struct `Map` in the current scope +error[E0599]: no method named `extend` found for struct `Map` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:87:67 | LL | v.iter().map(Box::new(|x| x * x) as Box i32>).extend(std::iter::once(100)); @@ -41,7 +41,7 @@ LL | wrapper.method(); - `Wrapper` and 2 more types -error[E0599]: no method named `other` found for struct `Wrapper` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:92:13 | LL | struct Wrapper(T); @@ -64,7 +64,7 @@ LL | wrapper.method(); - `Wrapper2<'a, i32, C>` - `Wrapper2<'a, i8, C>` -error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper2<'a, T, C>` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:98:13 | LL | struct Wrapper2<'a, T, const C: usize> { diff --git a/tests/ui/methods/probe-error-on-infinite-deref.rs b/tests/ui/methods/probe-error-on-infinite-deref.rs index 85c1c0c09c1..196d026438b 100644 --- a/tests/ui/methods/probe-error-on-infinite-deref.rs +++ b/tests/ui/methods/probe-error-on-infinite-deref.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes use std::ops::Deref; // Make sure that method probe error reporting doesn't get too tangled up diff --git a/tests/ui/methods/probe-error-on-infinite-deref.stderr b/tests/ui/methods/probe-error-on-infinite-deref.stderr index 57a9ca2eaa8..6148b001163 100644 --- a/tests/ui/methods/probe-error-on-infinite-deref.stderr +++ b/tests/ui/methods/probe-error-on-infinite-deref.stderr @@ -1,13 +1,15 @@ -error[E0055]: reached the recursion limit while auto-dereferencing `Wrap>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/probe-error-on-infinite-deref.rs:13:13 +error[E0055]: reached the recursion limit while auto-dereferencing `Wrap>>>>>>>>>>` + --> $DIR/probe-error-on-infinite-deref.rs:14:13 | LL | Wrap(1).lmao(); | ^^^^ deref recursion limit reached | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`probe_error_on_infinite_deref`) + = note: the full name for the type has been written to '$TEST_BUILD_DIR/probe-error-on-infinite-deref.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console error[E0599]: no method named `lmao` found for struct `Wrap<{integer}>` in the current scope - --> $DIR/probe-error-on-infinite-deref.rs:13:13 + --> $DIR/probe-error-on-infinite-deref.rs:14:13 | LL | struct Wrap(T); | -------------- method `lmao` not found for this struct diff --git a/tests/ui/methods/untrimmed-path-type.stderr b/tests/ui/methods/untrimmed-path-type.stderr index 1f3101ff4e7..ee07e2daa1e 100644 --- a/tests/ui/methods/untrimmed-path-type.stderr +++ b/tests/ui/methods/untrimmed-path-type.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `unknown` found for enum `Result` in the current scope +error[E0599]: no method named `unknown` found for enum `Result` in the current scope --> $DIR/untrimmed-path-type.rs:5:11 | LL | meow().unknown(); diff --git a/tests/ui/never_type/defaulted-never-note.fallback.stderr b/tests/ui/never_type/defaulted-never-note.fallback.stderr index fe9a924f64a..7526a399bf1 100644 --- a/tests/ui/never_type/defaulted-never-note.fallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.fallback.stderr @@ -8,7 +8,7 @@ LL | foo(_x); | = help: the trait `ImplementedForUnitButNotNever` is implemented for `()` = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) - = help: did you intend to use the type `()` here instead? + = help: you might have intended to use the type `()` here instead note: required by a bound in `foo` --> $DIR/defaulted-never-note.rs:25:11 | diff --git a/tests/ui/never_type/defaulted-never-note.rs b/tests/ui/never_type/defaulted-never-note.rs index badb5d4c51d..71f0d9fa5bb 100644 --- a/tests/ui/never_type/defaulted-never-note.rs +++ b/tests/ui/never_type/defaulted-never-note.rs @@ -35,7 +35,7 @@ fn smeg() { //[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()` //[fallback]~| NOTE this error might have been caused //[fallback]~| NOTE required by a bound introduced by this call - //[fallback]~| HELP did you intend + //[fallback]~| HELP you might have intended to use the type `()` } fn main() { diff --git a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr index c5463814475..610c687194b 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr @@ -10,7 +10,7 @@ LL | unconstrained_arg(return); () i32 = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) - = help: did you intend to use the type `()` here instead? + = help: you might have intended to use the type `()` here instead note: required by a bound in `unconstrained_arg` --> $DIR/diverging-fallback-no-leak.rs:12:25 | diff --git a/tests/ui/recursion/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs index 95e1f60d8b0..d4f13e9fa55 100644 --- a/tests/ui/recursion/issue-23122-2.rs +++ b/tests/ui/recursion/issue-23122-2.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes trait Next { type Next: Next; } diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index c5774cc1888..de402d65e6d 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -1,17 +1,19 @@ error[E0275]: overflow evaluating the requirement `<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` - --> $DIR/issue-23122-2.rs:10:17 + --> $DIR/issue-23122-2.rs:11:17 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) -note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` - --> $DIR/issue-23122-2.rs:9:15 +note: required for `GetNext<<<<... as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` + --> $DIR/issue-23122-2.rs:10:15 | LL | impl Next for GetNext { | - ^^^^ ^^^^^^^^^^ | | | unsatisfied trait bound introduced here + = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-23122-2.long-type-$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/recursion/issue-38591-non-regular-dropck-recursion.rs b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.rs index 7b7b1a9580b..c219a920bb4 100644 --- a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.rs +++ b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Zwrite-long-types-to-disk=yes // `S` is infinitely recursing so it's not possible to generate a finite // drop impl. // diff --git a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr index 409f63b91b6..cf3bc4578a7 100644 --- a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr +++ b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr @@ -1,10 +1,12 @@ error[E0320]: overflow while adding drop-check rules for `S` - --> $DIR/issue-38591-non-regular-dropck-recursion.rs:11:6 + --> $DIR/issue-38591-non-regular-dropck-recursion.rs:12:6 | LL | fn f(x: S) {} | ^ | - = note: overflowed on `S` + = note: overflowed on `S` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-38591-non-regular-dropck-recursion.long-type-$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/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index b720c168187..9194ce1ab17 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,6 +1,6 @@ //~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` //@ build-fail -//@ compile-flags: -Copt-level=0 +//@ compile-flags: -Copt-level=0 -Zwrite-long-types-to-disk=yes fn main() { let mut iter = 0u8..1; diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 600922f1e57..a245b001bad 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -13,9 +13,11 @@ LL | func(&mut iter.map(|x| x + 1)) error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` + = note: required for `&mut Map<&mut Range, {closure@issue-83150.rs:12:24}>` to implement `Iterator` = note: 65 redundant requirements hidden - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` + = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut ..., ...>, ...>, ...>, ...>` to implement `Iterator` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-83150.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/self/arbitrary_self_type_infinite_recursion.stderr b/tests/ui/self/arbitrary_self_type_infinite_recursion.stderr index 5e652efb364..2dadc5c2d33 100644 --- a/tests/ui/self/arbitrary_self_type_infinite_recursion.stderr +++ b/tests/ui/self/arbitrary_self_type_infinite_recursion.stderr @@ -32,7 +32,7 @@ LL | p.method(); | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`arbitrary_self_type_infinite_recursion`) -error[E0599]: no method named `method` found for struct `MySmartPtr` in the current scope +error[E0599]: no method named `method` found for struct `MySmartPtr` in the current scope --> $DIR/arbitrary_self_type_infinite_recursion.rs:21:5 | LL | struct MySmartPtr(T); diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr index a30cf605829..5d7f6142093 100644 --- a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr +++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `frobnicate_ref` found for struct `CppRef` in the current scope +error[E0599]: no method named `frobnicate_ref` found for struct `CppRef` in the current scope --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:29:17 | LL | struct CppRef(T); @@ -16,7 +16,7 @@ help: there is a method `frobnicate_cpp_ref` with a similar name LL | foo_cpp_ref.frobnicate_cpp_ref(); | ++++ -error[E0599]: no method named `frobnicate_self` found for struct `CppRef` in the current scope +error[E0599]: no method named `frobnicate_self` found for struct `CppRef` in the current scope --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:32:17 | LL | struct CppRef(T); diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs index d877dbe6075..28845890278 100644 --- a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs +++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs @@ -9,5 +9,5 @@ impl S { fn main() { Pin::new(S).x(); //~^ ERROR the trait bound `S: Deref` is not satisfied - //~| ERROR no method named `x` found for struct `Pin` in the current scope + //~| ERROR no method named `x` found for struct `Pin` in the current scope } diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr index 1811cd6753f..df226a9366a 100644 --- a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr +++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr @@ -15,7 +15,7 @@ LL | Pin::new(&S).x(); LL | Pin::new(&mut S).x(); | ++++ -error[E0599]: no method named `x` found for struct `Pin` in the current scope +error[E0599]: no method named `x` found for struct `Pin` in the current scope --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:17 | LL | Pin::new(S).x(); diff --git a/tests/ui/simd/libm_no_std_cant_float.stderr b/tests/ui/simd/libm_no_std_cant_float.stderr index 97e0b7efe2a..cc9aefaad5e 100644 --- a/tests/ui/simd/libm_no_std_cant_float.stderr +++ b/tests/ui/simd/libm_no_std_cant_float.stderr @@ -1,34 +1,34 @@ -error[E0599]: no method named `ceil` found for struct `Simd` in the current scope +error[E0599]: no method named `ceil` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:15:17 | LL | let _xc = x.ceil(); | ^^^^ method not found in `Simd` -error[E0599]: no method named `floor` found for struct `Simd` in the current scope +error[E0599]: no method named `floor` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:16:17 | LL | let _xf = x.floor(); | ^^^^^ method not found in `Simd` -error[E0599]: no method named `round` found for struct `Simd` in the current scope +error[E0599]: no method named `round` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:17:17 | LL | let _xr = x.round(); | ^^^^^ method not found in `Simd` -error[E0599]: no method named `trunc` found for struct `Simd` in the current scope +error[E0599]: no method named `trunc` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:18:17 | LL | let _xt = x.trunc(); | ^^^^^ method not found in `Simd` -error[E0599]: no method named `mul_add` found for struct `Simd` in the current scope +error[E0599]: no method named `mul_add` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:19:19 | LL | let _xfma = x.mul_add(x, x); | ^^^^^^^ method not found in `Simd` -error[E0599]: no method named `sqrt` found for struct `Simd` in the current scope +error[E0599]: no method named `sqrt` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:20:20 | LL | let _xsqrt = x.sqrt(); diff --git a/tests/ui/suggestions/enum-method-probe.fixed b/tests/ui/suggestions/enum-method-probe.fixed index b7fd6f112d5..1ce6a943c5b 100644 --- a/tests/ui/suggestions/enum-method-probe.fixed +++ b/tests/ui/suggestions/enum-method-probe.fixed @@ -14,7 +14,7 @@ impl Foo { fn test_result_in_result() -> Result<(), ()> { let res: Result<_, ()> = Ok(Foo); res?.get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP use the `?` operator Ok(()) } @@ -22,7 +22,7 @@ fn test_result_in_result() -> Result<(), ()> { async fn async_test_result_in_result() -> Result<(), ()> { let res: Result<_, ()> = Ok(Foo); res?.get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP use the `?` operator Ok(()) } @@ -30,21 +30,21 @@ async fn async_test_result_in_result() -> Result<(), ()> { fn test_result_in_unit_return() { let res: Result<_, ()> = Ok(Foo); res.expect("REASON").get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err` } async fn async_test_result_in_unit_return() { let res: Result<_, ()> = Ok(Foo); res.expect("REASON").get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err` } fn test_option_in_option() -> Option<()> { let res: Option<_> = Some(Foo); res?.get(); - //~^ ERROR no method named `get` found for enum `Option` in the current scope + //~^ ERROR no method named `get` found for enum `Option` in the current scope //~| HELP use the `?` operator Some(()) } @@ -52,7 +52,7 @@ fn test_option_in_option() -> Option<()> { fn test_option_in_unit_return() { let res: Option<_> = Some(Foo); res.expect("REASON").get(); - //~^ ERROR no method named `get` found for enum `Option` in the current scope + //~^ ERROR no method named `get` found for enum `Option` in the current scope //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None` } diff --git a/tests/ui/suggestions/enum-method-probe.rs b/tests/ui/suggestions/enum-method-probe.rs index cbb819b7c8c..dd3addbd0a3 100644 --- a/tests/ui/suggestions/enum-method-probe.rs +++ b/tests/ui/suggestions/enum-method-probe.rs @@ -14,7 +14,7 @@ impl Foo { fn test_result_in_result() -> Result<(), ()> { let res: Result<_, ()> = Ok(Foo); res.get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP use the `?` operator Ok(()) } @@ -22,7 +22,7 @@ fn test_result_in_result() -> Result<(), ()> { async fn async_test_result_in_result() -> Result<(), ()> { let res: Result<_, ()> = Ok(Foo); res.get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP use the `?` operator Ok(()) } @@ -30,21 +30,21 @@ async fn async_test_result_in_result() -> Result<(), ()> { fn test_result_in_unit_return() { let res: Result<_, ()> = Ok(Foo); res.get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err` } async fn async_test_result_in_unit_return() { let res: Result<_, ()> = Ok(Foo); res.get(); - //~^ ERROR no method named `get` found for enum `Result` in the current scope + //~^ ERROR no method named `get` found for enum `Result` in the current scope //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err` } fn test_option_in_option() -> Option<()> { let res: Option<_> = Some(Foo); res.get(); - //~^ ERROR no method named `get` found for enum `Option` in the current scope + //~^ ERROR no method named `get` found for enum `Option` in the current scope //~| HELP use the `?` operator Some(()) } @@ -52,7 +52,7 @@ fn test_option_in_option() -> Option<()> { fn test_option_in_unit_return() { let res: Option<_> = Some(Foo); res.get(); - //~^ ERROR no method named `get` found for enum `Option` in the current scope + //~^ ERROR no method named `get` found for enum `Option` in the current scope //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None` } diff --git a/tests/ui/suggestions/enum-method-probe.stderr b/tests/ui/suggestions/enum-method-probe.stderr index e66973d9d95..5aa0fc44c7b 100644 --- a/tests/ui/suggestions/enum-method-probe.stderr +++ b/tests/ui/suggestions/enum-method-probe.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `get` found for enum `Result` in the current scope +error[E0599]: no method named `get` found for enum `Result` in the current scope --> $DIR/enum-method-probe.rs:24:9 | LL | res.get(); @@ -14,7 +14,7 @@ help: use the `?` operator to extract the `Foo` value, propagating a `Result::Er LL | res?.get(); | + -error[E0599]: no method named `get` found for enum `Result` in the current scope +error[E0599]: no method named `get` found for enum `Result` in the current scope --> $DIR/enum-method-probe.rs:39:9 | LL | res.get(); @@ -30,7 +30,7 @@ help: consider using `Result::expect` to unwrap the `Foo` value, panicking if th LL | res.expect("REASON").get(); | +++++++++++++++++ -error[E0599]: no method named `get` found for enum `Result` in the current scope +error[E0599]: no method named `get` found for enum `Result` in the current scope --> $DIR/enum-method-probe.rs:16:9 | LL | res.get(); @@ -46,7 +46,7 @@ help: use the `?` operator to extract the `Foo` value, propagating a `Result::Er LL | res?.get(); | + -error[E0599]: no method named `get` found for enum `Result` in the current scope +error[E0599]: no method named `get` found for enum `Result` in the current scope --> $DIR/enum-method-probe.rs:32:9 | LL | res.get(); @@ -62,7 +62,7 @@ help: consider using `Result::expect` to unwrap the `Foo` value, panicking if th LL | res.expect("REASON").get(); | +++++++++++++++++ -error[E0599]: no method named `get` found for enum `Option` in the current scope +error[E0599]: no method named `get` found for enum `Option` in the current scope --> $DIR/enum-method-probe.rs:46:9 | LL | res.get(); @@ -78,7 +78,7 @@ help: use the `?` operator to extract the `Foo` value, propagating an `Option::N LL | res?.get(); | + -error[E0599]: no method named `get` found for enum `Option` in the current scope +error[E0599]: no method named `get` found for enum `Option` in the current scope --> $DIR/enum-method-probe.rs:54:9 | LL | res.get(); diff --git a/tests/ui/suggestions/field-has-method.rs b/tests/ui/suggestions/field-has-method.rs index d28b6ba546c..6e584d78338 100644 --- a/tests/ui/suggestions/field-has-method.rs +++ b/tests/ui/suggestions/field-has-method.rs @@ -17,7 +17,7 @@ struct InferOk { fn foo(i: InferOk) { let k = i.kind(); - //~^ ERROR no method named `kind` found for struct `InferOk` in the current scope + //~^ ERROR no method named `kind` found for struct `InferOk` in the current scope } fn main() {} diff --git a/tests/ui/suggestions/field-has-method.stderr b/tests/ui/suggestions/field-has-method.stderr index daff2db6418..adcb723e4f1 100644 --- a/tests/ui/suggestions/field-has-method.stderr +++ b/tests/ui/suggestions/field-has-method.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `kind` found for struct `InferOk` in the current scope +error[E0599]: no method named `kind` found for struct `InferOk` in the current scope --> $DIR/field-has-method.rs:19:15 | LL | struct InferOk { diff --git a/tests/ui/suggestions/inner_type.fixed b/tests/ui/suggestions/inner_type.fixed index 175a2a02acd..8174f8e204e 100644 --- a/tests/ui/suggestions/inner_type.fixed +++ b/tests/ui/suggestions/inner_type.fixed @@ -15,26 +15,26 @@ fn main() { let other_item = std::cell::RefCell::new(Struct { p: 42_u32 }); other_item.borrow().method(); - //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599] //~| HELP use `.borrow()` to borrow the `Struct`, panicking if a mutable borrow exists other_item.borrow_mut().some_mutable_method(); - //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599] + //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599] //~| HELP .borrow_mut()` to mutably borrow the `Struct`, panicking if any borrows exist let another_item = std::sync::Mutex::new(Struct { p: 42_u32 }); another_item.lock().unwrap().method(); - //~^ ERROR no method named `method` found for struct `std::sync::Mutex` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `std::sync::Mutex` in the current scope [E0599] //~| HELP use `.lock().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired let another_item = std::sync::RwLock::new(Struct { p: 42_u32 }); another_item.read().unwrap().method(); - //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599] //~| HELP use `.read().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired another_item.write().unwrap().some_mutable_method(); - //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599] + //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599] //~| HELP use `.write().unwrap()` to mutably borrow the `Struct`, blocking the current thread until it can be acquired } diff --git a/tests/ui/suggestions/inner_type.rs b/tests/ui/suggestions/inner_type.rs index ab021414f56..e4eaf07ca8b 100644 --- a/tests/ui/suggestions/inner_type.rs +++ b/tests/ui/suggestions/inner_type.rs @@ -15,26 +15,26 @@ fn main() { let other_item = std::cell::RefCell::new(Struct { p: 42_u32 }); other_item.method(); - //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599] //~| HELP use `.borrow()` to borrow the `Struct`, panicking if a mutable borrow exists other_item.some_mutable_method(); - //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599] + //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599] //~| HELP .borrow_mut()` to mutably borrow the `Struct`, panicking if any borrows exist let another_item = std::sync::Mutex::new(Struct { p: 42_u32 }); another_item.method(); - //~^ ERROR no method named `method` found for struct `std::sync::Mutex` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `std::sync::Mutex` in the current scope [E0599] //~| HELP use `.lock().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired let another_item = std::sync::RwLock::new(Struct { p: 42_u32 }); another_item.method(); - //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599] //~| HELP use `.read().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired another_item.some_mutable_method(); - //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599] + //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599] //~| HELP use `.write().unwrap()` to mutably borrow the `Struct`, blocking the current thread until it can be acquired } diff --git a/tests/ui/suggestions/inner_type.stderr b/tests/ui/suggestions/inner_type.stderr index 67ebb5789b7..017ddb5ad6d 100644 --- a/tests/ui/suggestions/inner_type.stderr +++ b/tests/ui/suggestions/inner_type.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `method` found for struct `RefCell` in the current scope +error[E0599]: no method named `method` found for struct `RefCell` in the current scope --> $DIR/inner_type.rs:17:16 | LL | other_item.method(); @@ -14,7 +14,7 @@ help: use `.borrow()` to borrow the `Struct`, panicking if a mutable borrow LL | other_item.borrow().method(); | +++++++++ -error[E0599]: no method named `some_mutable_method` found for struct `RefCell` in the current scope +error[E0599]: no method named `some_mutable_method` found for struct `RefCell` in the current scope --> $DIR/inner_type.rs:21:16 | LL | other_item.some_mutable_method(); @@ -30,7 +30,7 @@ help: use `.borrow_mut()` to mutably borrow the `Struct`, panicking if any LL | other_item.borrow_mut().some_mutable_method(); | +++++++++++++ -error[E0599]: no method named `method` found for struct `std::sync::Mutex` in the current scope +error[E0599]: no method named `method` found for struct `std::sync::Mutex` in the current scope --> $DIR/inner_type.rs:27:18 | LL | another_item.method(); @@ -46,7 +46,7 @@ help: use `.lock().unwrap()` to borrow the `Struct`, blocking the current t LL | another_item.lock().unwrap().method(); | ++++++++++++++++ -error[E0599]: no method named `method` found for struct `RwLock` in the current scope +error[E0599]: no method named `method` found for struct `RwLock` in the current scope --> $DIR/inner_type.rs:33:18 | LL | another_item.method(); @@ -62,7 +62,7 @@ help: use `.read().unwrap()` to borrow the `Struct`, blocking the current t LL | another_item.read().unwrap().method(); | ++++++++++++++++ -error[E0599]: no method named `some_mutable_method` found for struct `RwLock` in the current scope +error[E0599]: no method named `some_mutable_method` found for struct `RwLock` in the current scope --> $DIR/inner_type.rs:37:18 | LL | another_item.some_mutable_method(); diff --git a/tests/ui/suggestions/inner_type2.rs b/tests/ui/suggestions/inner_type2.rs index fac68c053eb..7082862f409 100644 --- a/tests/ui/suggestions/inner_type2.rs +++ b/tests/ui/suggestions/inner_type2.rs @@ -16,11 +16,11 @@ thread_local! { fn main() { STRUCT.method(); - //~^ ERROR no method named `method` found for struct `LocalKey` in the current scope [E0599] + //~^ ERROR no method named `method` found for struct `LocalKey` in the current scope [E0599] //~| HELP use `with` or `try_with` to access thread local storage let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 }); item.method(); - //~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599] + //~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599] //~| HELP if this `MaybeUninit>` has been initialized, use one of the `assume_init` methods to access the inner value } diff --git a/tests/ui/suggestions/inner_type2.stderr b/tests/ui/suggestions/inner_type2.stderr index 984366123c8..e6cb2048522 100644 --- a/tests/ui/suggestions/inner_type2.stderr +++ b/tests/ui/suggestions/inner_type2.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `method` found for struct `LocalKey` in the current scope +error[E0599]: no method named `method` found for struct `LocalKey` in the current scope --> $DIR/inner_type2.rs:18:12 | LL | STRUCT.method(); @@ -11,7 +11,7 @@ note: the method `method` exists on the type `Struct` LL | pub fn method(&self) {} | ^^^^^^^^^^^^^^^^^^^^ -error[E0599]: no method named `method` found for union `MaybeUninit` in the current scope +error[E0599]: no method named `method` found for union `MaybeUninit` in the current scope --> $DIR/inner_type2.rs:23:10 | LL | item.method(); diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.rs b/tests/ui/traits/issue-91949-hangs-on-recursion.rs index 7c9ae09349a..434cf00fc4b 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.rs +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.rs @@ -1,6 +1,6 @@ //~ ERROR overflow evaluating the requirement ` as Iterator>::Item == ()` //@ build-fail -//@ compile-flags: -Zinline-mir=no +//@ compile-flags: -Zinline-mir=no -Zwrite-long-types-to-disk=yes // Regression test for #91949. // This hanged *forever* on 1.56, fixed by #90423. diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr index c2f09371cf7..a179107885a 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr @@ -24,7 +24,9 @@ LL | impl> Iterator for IteratorOfWrapped { | | | unsatisfied trait bound introduced here = note: 256 redundant requirements hidden - = note: required for `IteratorOfWrapped<(), Map>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48}>>` to implement `Iterator` + = note: required for `IteratorOfWrapped<(), Map>, ...>>` to implement `Iterator` + = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-91949-hangs-on-recursion.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 1 previous error; 1 warning emitted -- cgit 1.4.1-3-g733a5 From 2054a0c56b063c195d316e4ff44d0c9f8ad2c012 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 28 Jul 2025 03:00:24 -0700 Subject: mbe: In error messages, don't assume attributes are always proc macros Now that `macro_rules` macros can define attribute rules, make sure error messages account for that. --- compiler/rustc_errors/src/emitter.rs | 2 +- src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr | 2 +- tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr | 4 ++-- tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr | 4 ++-- tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr | 2 +- tests/ui/allocator/not-an-allocator.stderr | 8 ++++---- tests/ui/allocator/two-allocators.stderr | 2 +- tests/ui/custom_test_frameworks/mismatch.stderr | 2 +- tests/ui/proc-macro/span-from-proc-macro.stderr | 2 +- .../termination-trait-test-wrong-type.stderr | 2 +- tests/ui/test-attrs/issue-12997-2.stderr | 2 +- tests/ui/test-attrs/test-function-signature.stderr | 2 +- 12 files changed, 17 insertions(+), 17 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 84970e7c162..0c839f94f7f 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -409,7 +409,7 @@ pub trait Emitter { if !redundant_span || always_backtrace { let msg: Cow<'static, _> = match trace.kind { ExpnKind::Macro(MacroKind::Attr, _) => { - "this procedural macro expansion".into() + "this attribute macro expansion".into() } ExpnKind::Macro(MacroKind::Derive, _) => { "this derive macro expansion".into() diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr index 29c56ca81f7..a2a4be30eca 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr @@ -11,7 +11,7 @@ note: inside `_::__rg_oom` --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC | LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion + | ---------------------- in this attribute macro expansion LL | fn alloc_error_handler(layout: Layout) -> ! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr index 15314fac37b..aad45c422e2 100644 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr +++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1 | LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion + | ---------------------- in this attribute macro expansion LL | // fn oom( LL | || info: &Layout, LL | || ) -> () @@ -23,7 +23,7 @@ error[E0308]: mismatched types --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1 | LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion + | ---------------------- in this attribute macro expansion LL | // fn oom( LL | || info: &Layout, LL | || ) -> () diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr index 2ab42638411..581d1947419 100644 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr +++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 | LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion + | ---------------------- in this attribute macro expansion LL | // fn oom( LL | || info: Layout, LL | || ) { @@ -31,7 +31,7 @@ error[E0308]: mismatched types --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 | LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion + | ---------------------- in this attribute macro expansion LL | // fn oom( LL | || info: Layout, LL | || ) { diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr index 3a410174f54..91147df71eb 100644 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr +++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/alloc-error-handler-bad-signature-3.rs:10:1 | LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion + | ---------------------- in this attribute macro expansion LL | fn oom() -> ! { | _-^^^^^^^^^^^^ LL | | loop {} diff --git a/tests/ui/allocator/not-an-allocator.stderr b/tests/ui/allocator/not-an-allocator.stderr index 079bf9334eb..f33a698ed78 100644 --- a/tests/ui/allocator/not-an-allocator.stderr +++ b/tests/ui/allocator/not-an-allocator.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:11 | LL | #[global_allocator] - | ------------------- in this procedural macro expansion + | ------------------- in this attribute macro expansion LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | @@ -12,7 +12,7 @@ error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:11 | LL | #[global_allocator] - | ------------------- in this procedural macro expansion + | ------------------- in this attribute macro expansion LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | @@ -23,7 +23,7 @@ error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:11 | LL | #[global_allocator] - | ------------------- in this procedural macro expansion + | ------------------- in this attribute macro expansion LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | @@ -34,7 +34,7 @@ error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied --> $DIR/not-an-allocator.rs:2:11 | LL | #[global_allocator] - | ------------------- in this procedural macro expansion + | ------------------- in this attribute macro expansion LL | static A: usize = 0; | ^^^^^ the trait `GlobalAlloc` is not implemented for `usize` | diff --git a/tests/ui/allocator/two-allocators.stderr b/tests/ui/allocator/two-allocators.stderr index 5308232a20b..1a9a5910eec 100644 --- a/tests/ui/allocator/two-allocators.stderr +++ b/tests/ui/allocator/two-allocators.stderr @@ -4,7 +4,7 @@ error: cannot define multiple global allocators LL | static A: System = System; | -------------------------- previous global allocator defined here LL | #[global_allocator] - | ------------------- in this procedural macro expansion + | ------------------- in this attribute macro expansion LL | static B: System = System; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot define a new global allocator diff --git a/tests/ui/custom_test_frameworks/mismatch.stderr b/tests/ui/custom_test_frameworks/mismatch.stderr index c7798635fbf..7cdfaa9e804 100644 --- a/tests/ui/custom_test_frameworks/mismatch.stderr +++ b/tests/ui/custom_test_frameworks/mismatch.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `TestDescAndFn: Testable` is not satisfied --> $DIR/mismatch.rs:9:1 | LL | #[test] - | ------- in this procedural macro expansion + | ------- in this attribute macro expansion LL | fn wrong_kind(){} | ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn` | diff --git a/tests/ui/proc-macro/span-from-proc-macro.stderr b/tests/ui/proc-macro/span-from-proc-macro.stderr index 452c04df877..c79ab04eadf 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.stderr +++ b/tests/ui/proc-macro/span-from-proc-macro.stderr @@ -10,7 +10,7 @@ LL | field: MissingType ::: $DIR/span-from-proc-macro.rs:8:1 | LL | #[error_from_attribute] - | ----------------------- in this procedural macro expansion + | ----------------------- in this attribute macro expansion error[E0412]: cannot find type `OtherMissingType` in this scope --> $DIR/auxiliary/span-from-proc-macro.rs:42:21 diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr index b89c5e8dda8..020c2e6f241 100644 --- a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr +++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `f32: Termination` is not satisfied --> $DIR/termination-trait-test-wrong-type.rs:6:31 | LL | #[test] - | ------- in this procedural macro expansion + | ------- in this attribute macro expansion LL | fn can_parse_zero_as_f32() -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Termination` is not implemented for `f32` | diff --git a/tests/ui/test-attrs/issue-12997-2.stderr b/tests/ui/test-attrs/issue-12997-2.stderr index 1123630a4a1..41d0074ad1a 100644 --- a/tests/ui/test-attrs/issue-12997-2.stderr +++ b/tests/ui/test-attrs/issue-12997-2.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-12997-2.rs:8:1 | LL | #[bench] - | -------- in this procedural macro expansion + | -------- in this attribute macro expansion LL | fn bar(x: isize) { } | ^^^^^^^^^^^^^^^^^^^^ | | diff --git a/tests/ui/test-attrs/test-function-signature.stderr b/tests/ui/test-attrs/test-function-signature.stderr index c025163c0bd..55d09970b32 100644 --- a/tests/ui/test-attrs/test-function-signature.stderr +++ b/tests/ui/test-attrs/test-function-signature.stderr @@ -26,7 +26,7 @@ error[E0277]: the trait bound `i32: Termination` is not satisfied --> $DIR/test-function-signature.rs:9:13 | LL | #[test] - | ------- in this procedural macro expansion + | ------- in this attribute macro expansion LL | fn bar() -> i32 { | ^^^ the trait `Termination` is not implemented for `i32` | -- cgit 1.4.1-3-g733a5 From cf1a1b7b76a937afae997594d931b64956e74a4f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sat, 9 Aug 2025 15:47:20 +0800 Subject: Use `eq_ignore_ascii_case` to avoid heap alloc in `detect_confuse_type` Signed-off-by: xizheyin --- compiler/rustc_errors/src/emitter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 84970e7c162..652e2ac63e6 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -3546,7 +3546,7 @@ pub fn detect_confusion_type(sm: &SourceMap, suggested: &str, sp: Span) -> Confu for (f, s) in iter::zip(found.chars(), suggested.chars()) { if f != s { - if f.to_lowercase().to_string() == s.to_lowercase().to_string() { + if f.eq_ignore_ascii_case(&s) { // Check for case differences (any character that differs only in case) if ascii_confusables.contains(&f) || ascii_confusables.contains(&s) { has_case_diff = true; -- cgit 1.4.1-3-g733a5 From 1aa5668d20d53976860d141a66aa727e425e1079 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 28 Jul 2025 02:01:46 +0000 Subject: Point at the `Fn()` or `FnMut()` bound that coerced a closure, which caused a move error When encountering a move error involving a closure because the captured value isn't `Copy`, and the obligation comes from a bound on a type parameter that requires `Fn` or `FnMut`, we point at it and explain that an `FnOnce` wouldn't cause the move error. ``` error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure --> f111.rs:15:25 | 14 | fn do_stuff(foo: Option) { | --- ----------- move occurs because `foo` has type `Option`, which does not implement the `Copy` trait | | | captured outer variable 15 | require_fn_trait(|| async { | -- ^^^^^ `foo` is moved here | | | captured by this `Fn` closure 16 | if foo.map_or(false, |f| f.foo()) { | --- variable moved due to use in coroutine | help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once --> f111.rs:12:53 | 12 | fn require_fn_trait>(_: impl Fn() -> F) {} | ^^^^^^^^^ help: consider cloning the value if the performance cost is acceptable | 16 | if foo.clone().map_or(false, |f| f.foo()) { | ++++++++ ``` --- .../rustc_borrowck/src/diagnostics/move_errors.rs | 40 +++++- compiler/rustc_errors/src/diagnostic.rs | 7 +- tests/ui/borrowck/borrowck-in-static.stderr | 1 + tests/ui/borrowck/borrowck-move-by-capture.stderr | 5 + tests/ui/borrowck/issue-103624.stderr | 5 + .../borrowck/issue-87456-point-to-closure.stderr | 5 + ...res-move-upvar-from-non-once-ref-closure.stderr | 5 + tests/ui/issues/issue-4335.stderr | 1 + ...-type-move-out-of-closure-env-issue-1965.stderr | 5 + .../issue-52663-span-decl-captured-variable.stderr | 5 + .../borrowck-call-is-borrow-issue-12224.stderr | 1 + .../dont-suggest-ref/move-into-closure.rs | 21 +++ .../dont-suggest-ref/move-into-closure.stderr | 147 ++++++++++++++++++--- tests/ui/suggestions/option-content-move2.stderr | 11 ++ tests/ui/suggestions/option-content-move3.stderr | 12 ++ .../unboxed-closure-illegal-move.stderr | 22 +++ 16 files changed, 268 insertions(+), 25 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 1067f1e40ef..b24cb012d2b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -9,7 +9,7 @@ use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; -use rustc_span::{BytePos, ExpnKind, MacroKind, Span}; +use rustc_span::{BytePos, DUMMY_SP, ExpnKind, MacroKind, Span}; use rustc_trait_selection::error_reporting::traits::FindExprBySpan; use rustc_trait_selection::infer::InferCtxtExt; use tracing::debug; @@ -507,12 +507,50 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ); let closure_span = tcx.def_span(def_id); + let mut clause_span = DUMMY_SP; + let typck_result = self.infcx.tcx.typeck(self.mir_def_id()); + if let Some(closure_def_id) = def_id.as_local() + && let hir::Node::Expr(expr) = tcx.hir_node_by_def_id(closure_def_id) + && let hir::Node::Expr(parent) = tcx.parent_hir_node(expr.hir_id) + && let hir::ExprKind::Call(callee, _) = parent.kind + && let Some(ty) = typck_result.node_type_opt(callee.hir_id) + && let ty::FnDef(fn_def_id, args) = ty.kind() + && let predicates = tcx.predicates_of(fn_def_id).instantiate(tcx, args) + && let Some((_, span)) = + predicates.predicates.iter().zip(predicates.spans.iter()).find( + |(pred, _)| match pred.as_trait_clause() { + Some(clause) + if let ty::Closure(clause_closure_def_id, _) = + clause.self_ty().skip_binder().kind() + && clause_closure_def_id == def_id + && (tcx.lang_items().fn_mut_trait() + == Some(clause.def_id()) + || tcx.lang_items().fn_trait() + == Some(clause.def_id())) => + { + // Found `` + true + } + _ => false, + }, + ) + { + // We point at the `Fn()` or `FnMut()` bound that coerced the closure, which + // could be changed to `FnOnce()` to avoid the move error. + clause_span = *span; + } + self.cannot_move_out_of(span, &place_description) .with_span_label(upvar_span, "captured outer variable") .with_span_label( closure_span, format!("captured by this `{closure_kind}` closure"), ) + .with_span_help( + clause_span, + "`Fn` and `FnMut` closures require captured values to be able to be \ + consumed multiple times, but an `FnOnce` consume them only once", + ) } _ => { let source = self.borrowed_content_source(deref_base); diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 5a5563c7bb2..98be37fd84b 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -847,17 +847,18 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } + with_fn! { with_span_help, /// Prints the span with some help above it. /// This is like [`Diag::help()`], but it gets its own span. #[rustc_lint_diagnostics] - pub fn span_help>( + pub fn span_help( &mut self, - sp: S, + sp: impl Into, msg: impl Into, ) -> &mut Self { self.sub(Level::Help, msg, sp.into()); self - } + } } /// Disallow attaching suggestions to this diagnostic. /// Any suggestions attached e.g. with the `span_suggestion_*` methods diff --git a/tests/ui/borrowck/borrowck-in-static.stderr b/tests/ui/borrowck/borrowck-in-static.stderr index 9bcf64dd62e..d85f6f5fdd5 100644 --- a/tests/ui/borrowck/borrowck-in-static.stderr +++ b/tests/ui/borrowck/borrowck-in-static.stderr @@ -10,6 +10,7 @@ LL | Box::new(|| x) | | | captured by this `Fn` closure | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: consider cloning the value if the performance cost is acceptable | LL | Box::new(|| x.clone()) diff --git a/tests/ui/borrowck/borrowck-move-by-capture.stderr b/tests/ui/borrowck/borrowck-move-by-capture.stderr index 732af1593d6..e9e05440766 100644 --- a/tests/ui/borrowck/borrowck-move-by-capture.stderr +++ b/tests/ui/borrowck/borrowck-move-by-capture.stderr @@ -12,6 +12,11 @@ LL | let _h = to_fn_once(move || -> isize { *bar }); | | | `bar` is moved here | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/borrowck-move-by-capture.rs:3:37 + | +LL | fn to_fn_mut>(f: F) -> F { f } + | ^^^^^^^^ help: consider cloning the value before moving it into the closure | LL ~ let value = bar.clone(); diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index af65deb16dc..ef022808886 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -13,6 +13,11 @@ LL | LL | self.b; | ^^^^^^ `self.b` is moved here | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/issue-103624.rs:7:36 + | +LL | async fn spawn_blocking(f: impl (Fn() -> T) + Send + Sync + 'static) -> T { + | ^^^^^^^^^^^ note: if `StructB` implemented `Clone`, you could clone the value --> $DIR/issue-103624.rs:23:1 | diff --git a/tests/ui/borrowck/issue-87456-point-to-closure.stderr b/tests/ui/borrowck/issue-87456-point-to-closure.stderr index a0c7cac2add..043e336cd86 100644 --- a/tests/ui/borrowck/issue-87456-point-to-closure.stderr +++ b/tests/ui/borrowck/issue-87456-point-to-closure.stderr @@ -10,6 +10,11 @@ LL | LL | let _foo: String = val; | ^^^ move occurs because `val` has type `String`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/issue-87456-point-to-closure.rs:3:24 + | +LL | fn take_mut(_val: impl FnMut()) {} + | ^^^^^^^ help: consider borrowing here | LL | let _foo: String = &val; diff --git a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr index 177e9c8d248..d3333041310 100644 --- a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr +++ b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr @@ -10,6 +10,11 @@ LL | y.into_iter(); | | | move occurs because `y` has type `Vec`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:5:28 + | +LL | fn call(f: F) where F : Fn() { + | ^^^^ note: `into_iter` takes ownership of the receiver `self`, which moves `y` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior diff --git a/tests/ui/issues/issue-4335.stderr b/tests/ui/issues/issue-4335.stderr index 42ac6322564..b6d8f086163 100644 --- a/tests/ui/issues/issue-4335.stderr +++ b/tests/ui/issues/issue-4335.stderr @@ -10,6 +10,7 @@ LL | id(Box::new(|| *v)) | | | captured by this `FnMut` closure | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-4335.rs:5:10 | diff --git a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr index 51d0f85c031..dfc983bf487 100644 --- a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr +++ b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr @@ -10,6 +10,11 @@ LL | let _f = to_fn(|| test(i)); | | | captured by this `Fn` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:3:33 + | +LL | fn to_fn>(f: F) -> F { f } + | ^^^^^ help: consider cloning the value if the performance cost is acceptable | LL | let _f = to_fn(|| test(i.clone())); diff --git a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr index 57546037006..7f9a8e50dae 100644 --- a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr +++ b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr @@ -10,6 +10,11 @@ LL | expect_fn(|| drop(x.0)); | | | captured by this `Fn` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/issue-52663-span-decl-captured-variable.rs:1:33 + | +LL | fn expect_fn(f: F) where F : Fn() { + | ^^^^ help: consider cloning the value if the performance cost is acceptable | LL | expect_fn(|| drop(x.0.clone())); diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr index f37dc320fa3..8081f7b3a8b 100644 --- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -44,6 +44,7 @@ LL | LL | foo(f); | ^ move occurs because `f` has type `{closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58}`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: consider cloning the value if the performance cost is acceptable | LL | foo(f.clone()); diff --git a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs index 44eac3691a3..0154810f564 100644 --- a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs +++ b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs @@ -11,8 +11,29 @@ struct X(Y); struct Y; fn consume_fn(_f: F) { } +//~^ HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures fn consume_fnmut(_f: F) { } +//~^ HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures pub fn main() { } diff --git a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr index edda2cbc735..d9ed25983d6 100644 --- a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr +++ b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:28:21 + --> $DIR/move-into-closure.rs:49:21 | LL | let x = X(Y); | - captured outer variable @@ -12,13 +12,18 @@ LL | let X(_t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | let X(_t) = &x; | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:31:34 + --> $DIR/move-into-closure.rs:52:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -32,13 +37,18 @@ LL | if let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | if let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:34:37 + --> $DIR/move-into-closure.rs:55:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -52,13 +62,18 @@ LL | while let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | while let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:37:15 + --> $DIR/move-into-closure.rs:58:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -75,13 +90,18 @@ LL | Either::One(_t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:43:15 + --> $DIR/move-into-closure.rs:64:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -98,13 +118,18 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:51:25 + --> $DIR/move-into-closure.rs:72:25 | LL | let x = X(Y); | - captured outer variable @@ -118,13 +143,18 @@ LL | let X(mut _t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | let X(mut _t) = &x; | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:54:38 + --> $DIR/move-into-closure.rs:75:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -138,13 +168,18 @@ LL | if let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | if let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:57:41 + --> $DIR/move-into-closure.rs:78:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -158,13 +193,18 @@ LL | while let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | while let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:60:15 + --> $DIR/move-into-closure.rs:81:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -181,13 +221,18 @@ LL | Either::One(mut _t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:66:15 + --> $DIR/move-into-closure.rs:87:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -204,13 +249,18 @@ LL | Either::One(mut _t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:85:21 + --> $DIR/move-into-closure.rs:106:21 | LL | let x = X(Y); | - captured outer variable @@ -223,13 +273,18 @@ LL | let X(_t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | let X(_t) = &x; | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:88:34 + --> $DIR/move-into-closure.rs:109:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -243,13 +298,18 @@ LL | if let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | if let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:91:37 + --> $DIR/move-into-closure.rs:112:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -263,13 +323,18 @@ LL | while let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | while let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:94:15 + --> $DIR/move-into-closure.rs:115:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -286,13 +351,18 @@ LL | Either::One(_t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:100:15 + --> $DIR/move-into-closure.rs:121:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -309,13 +379,18 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:108:25 + --> $DIR/move-into-closure.rs:129:25 | LL | let x = X(Y); | - captured outer variable @@ -329,13 +404,18 @@ LL | let X(mut _t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | let X(mut _t) = &x; | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:111:38 + --> $DIR/move-into-closure.rs:132:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -349,13 +429,18 @@ LL | if let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | if let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:114:41 + --> $DIR/move-into-closure.rs:135:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -369,13 +454,18 @@ LL | while let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | while let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:117:15 + --> $DIR/move-into-closure.rs:138:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -392,13 +482,18 @@ LL | Either::One(mut _t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:123:15 + --> $DIR/move-into-closure.rs:144:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -415,13 +510,18 @@ LL | Either::One(mut _t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:130:15 + --> $DIR/move-into-closure.rs:151:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -438,6 +538,11 @@ LL | Either::One(mut _t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &em { diff --git a/tests/ui/suggestions/option-content-move2.stderr b/tests/ui/suggestions/option-content-move2.stderr index c73e874b403..c8aa6667b58 100644 --- a/tests/ui/suggestions/option-content-move2.stderr +++ b/tests/ui/suggestions/option-content-move2.stderr @@ -14,6 +14,11 @@ LL | LL | var = Some(NotCopyable); | --- variable moved due to use in closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move2.rs:5:12 + | +LL | fn func H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move2.rs:1:1 | @@ -38,6 +43,12 @@ LL | move || { LL | LL | var = Some(NotCopyableButCloneable); | --- variable moved due to use in closure + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move2.rs:5:12 + | +LL | fn func H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr index 68c52352a65..2c9a86c036b 100644 --- a/tests/ui/suggestions/option-content-move3.stderr +++ b/tests/ui/suggestions/option-content-move3.stderr @@ -9,6 +9,7 @@ LL | move || { LL | let x = var; | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | @@ -37,6 +38,11 @@ LL | move || { LL | let x = var; | --- variable moved due to use in closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move3.rs:6:12 + | +LL | fn func H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | @@ -57,6 +63,7 @@ LL | move || { LL | let x = var; | ^^^ move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: consider borrowing here | LL | let x = &var; @@ -77,6 +84,11 @@ LL | move || { LL | let x = var; | --- variable moved due to use in closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move3.rs:6:12 + | +LL | fn func H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ help: consider cloning the value before moving it into the closure | LL ~ { diff --git a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr index 8d9a61cb681..9d87402a15b 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr @@ -10,6 +10,11 @@ LL | let f = to_fn(|| drop(x)); | | | captured by this `Fn` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:7:33 + | +LL | fn to_fn>(f: F) -> F { f } + | ^^^^^ help: consider cloning the value if the performance cost is acceptable | LL | let f = to_fn(|| drop(x.clone())); @@ -27,6 +32,11 @@ LL | let f = to_fn_mut(|| drop(x)); | | | captured by this `FnMut` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:8:37 + | +LL | fn to_fn_mut>(f: F) -> F { f } + | ^^^^^^^^ help: consider cloning the value if the performance cost is acceptable | LL | let f = to_fn_mut(|| drop(x.clone())); @@ -43,6 +53,12 @@ LL | let f = to_fn(move || drop(x)); | ------- ^ `x` is moved here | | | captured by this `Fn` closure + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:7:33 + | +LL | fn to_fn>(f: F) -> F { f } + | ^^^^^ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure --> $DIR/unboxed-closure-illegal-move.rs:32:40 @@ -55,6 +71,12 @@ LL | let f = to_fn_mut(move || drop(x)); | ------- ^ `x` is moved here | | | captured by this `FnMut` closure + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:8:37 + | +LL | fn to_fn_mut>(f: F) -> F { f } + | ^^^^^^^^ error: aborting due to 4 previous errors -- cgit 1.4.1-3-g733a5