From 81c068a7a6cd6c7efb85e372769ca6deb4a892ea Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 14 Feb 2024 13:31:50 +0300 Subject: [PATCH 01/10] install tools documentations Previously, we were trying to install all doc files under "share/doc/rust" which caused `rust-installer` tool to create backup files (*.old) due to filename conflicts. With this change, doc files is now installed under "share/doc/{package}", where {package} could be rustc, cargo, clippy, etc. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/install.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 1c565e7f7cc06..0225f8f24a5ef 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -95,7 +95,7 @@ fn install_sh( } let datadir = prefix.join(default_path(&builder.config.datadir, "share")); - let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust")); + let docdir = prefix.join(default_path(&builder.config.docdir, &format!("share/doc/{package}"))); let mandir = prefix.join(default_path(&builder.config.mandir, "share/man")); let libdir = prefix.join(default_path(&builder.config.libdir, "lib")); let bindir = prefix.join(&builder.config.bindir); // Default in config.rs From e4a15d4f042ee9010cbe7f9d26becd52c30f4dec Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 14 Feb 2024 13:52:45 +0300 Subject: [PATCH 02/10] don't use entire sysroot binary path for rustc tarballs Previously, we used the entire sysroot binary path to prepare rustc tarballs. Since we also copy tool binaries to the sysroot binary path, installing rustc and tools with `x install` results in attempting to install the same binaries more than once. This causes rust-installer to create backup files (*.old) due to file conflicts. This change fixes that. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/dist.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f50026368dabd..44dda4c67936c 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -398,10 +398,11 @@ impl Step for Rustc { let host = compiler.host; let src = builder.sysroot(compiler); - // Copy rustc/rustdoc binaries + // Copy rustc binary + builder.install(&src.join("bin").join("rustc"), &image.join("bin"), 0o755); t!(fs::create_dir_all(image.join("bin"))); - builder.cp_r(&src.join("bin"), &image.join("bin")); + // If enabled, copy rustdoc binary if builder .config .tools From 0925ff8300ed724f1a1760c0bedd7522f49b3203 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 14 Feb 2024 19:10:49 +0300 Subject: [PATCH 03/10] use build.rustc config and skip-stage0-validation flag This change helps us to bypass downloading the beta compiler in bootstrap tests. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/tests.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 0ae466eca7d7c..6ac573c68df18 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -11,9 +11,15 @@ use std::{ }; fn parse(config: &str) -> Config { - Config::parse_inner(&["check".to_owned(), "--config=/does/not/exist".to_owned()], |&_| { - toml::from_str(config).unwrap() - }) + let config = format!("{config} \r\n build.rustc = \"/does-not-exists\" "); + Config::parse_inner( + &[ + "check".to_owned(), + "--config=/does/not/exist".to_owned(), + "--skip-stage0-validation".to_owned(), + ], + |&_| toml::from_str(&config).unwrap(), + ) } #[test] From b80fc5d4e8ce95a00b14a50e8ee0561b64736480 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 14 Feb 2024 14:17:27 +0000 Subject: [PATCH 04/10] errors: only eagerly translate subdiagnostics Subdiagnostics don't need to be lazily translated, they can always be eagerly translated. Eager translation is slightly more complex as we need to have a `DiagCtxt` available to perform the translation, which involves slightly more threading of that context. This slight increase in complexity should enable later simplifications - like passing `DiagCtxt` into `AddToDiagnostic` and moving Fluent messages into the diagnostic structs rather than having them in separate files (working on that was what led to this change). Signed-off-by: David Wood --- .../src/diagnostics/conflict_errors.rs | 89 +++++--- .../rustc_borrowck/src/diagnostics/mod.rs | 202 +++++++++++------- .../src/diagnostics/move_errors.rs | 47 ++-- .../src/diagnostics/mutability_errors.rs | 2 +- .../src/diagnostics/region_errors.rs | 10 +- compiler/rustc_codegen_gcc/src/errors.rs | 2 +- compiler/rustc_codegen_llvm/src/errors.rs | 2 +- .../src/transform/check_consts/ops.rs | 2 +- compiler/rustc_error_messages/src/lib.rs | 36 ++-- compiler/rustc_errors/src/diagnostic.rs | 11 +- .../rustc_errors/src/diagnostic_builder.rs | 3 - compiler/rustc_errors/src/emitter.rs | 23 ++ compiler/rustc_errors/src/lib.rs | 71 ++++-- compiler/rustc_errors/src/translation.rs | 4 +- compiler/rustc_expand/src/mbe/diagnostics.rs | 15 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 24 ++- compiler/rustc_hir_typeck/src/expr.rs | 7 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 96 +++++---- .../rustc_hir_typeck/src/method/suggest.rs | 27 +-- compiler/rustc_hir_typeck/src/op.rs | 2 +- .../src/infer/error_reporting/mod.rs | 4 +- .../src/infer/error_reporting/note.rs | 2 +- .../src/infer/error_reporting/suggest.rs | 33 +-- compiler/rustc_lint/src/lints.rs | 2 +- .../src/diagnostics/diagnostic_builder.rs | 39 +--- .../src/thir/pattern/check_match.rs | 2 +- compiler/rustc_mir_transform/src/errors.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 13 +- compiler/rustc_parse/src/parser/pat.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 24 ++- compiler/rustc_resolve/src/imports.rs | 4 +- .../rustc_resolve/src/late/diagnostics.rs | 24 ++- compiler/rustc_session/src/parse.rs | 10 +- .../src/traits/error_reporting/suggestions.rs | 7 +- src/tools/miri/src/diagnostics.rs | 2 +- src/tools/rustfmt/src/parse/session.rs | 11 + .../session-diagnostic/diagnostic-derive.rs | 10 +- .../diagnostic-derive.stderr | 44 ++-- 43 files changed, 532 insertions(+), 388 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 18cf6f64fbc03..2b0c0e939f59b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -229,7 +229,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { seen_spans.insert(move_span); } - use_spans.var_path_only_subdiag(&mut err, desired_action); + use_spans.var_path_only_subdiag(self.dcx(), &mut err, desired_action); if !is_loop_move { err.span_label( @@ -291,18 +291,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if needs_note { if let Some(local) = place.as_local() { let span = self.body.local_decls[local].source_info.span; - err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { - is_partial_move, - ty, - place: ¬e_msg, - span, - }); + err.subdiagnostic( + self.dcx(), + crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move, + ty, + place: ¬e_msg, + span, + }, + ); } else { - err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note { - is_partial_move, - ty, - place: ¬e_msg, - }); + err.subdiagnostic( + self.dcx(), + crate::session_diagnostics::TypeNoCopy::Note { + is_partial_move, + ty, + place: ¬e_msg, + }, + ); }; } @@ -557,7 +563,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { E0381, "{used} binding {desc}{isnt_initialized}" ); - use_spans.var_path_only_subdiag(&mut err, desired_action); + use_spans.var_path_only_subdiag(self.dcx(), &mut err, desired_action); if let InitializationRequiringAction::PartialAssignment | InitializationRequiringAction::Assignment = desired_action @@ -848,9 +854,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &value_msg, ); - borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow); + borrow_spans.var_path_only_subdiag( + self.dcx(), + &mut err, + crate::InitializationRequiringAction::Borrow, + ); - move_spans.var_subdiag(None, &mut err, None, |kind, var_span| { + move_spans.var_subdiag(self.dcx(), &mut err, None, |kind, var_span| { use crate::session_diagnostics::CaptureVarCause::*; match kind { hir::ClosureKind::Coroutine(_) => MoveUseInCoroutine { var_span }, @@ -895,7 +905,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_span, &self.describe_any_place(borrow.borrowed_place.as_ref()), ); - borrow_spans.var_subdiag(None, &mut err, Some(borrow.kind), |kind, var_span| { + borrow_spans.var_subdiag(self.dcx(), &mut err, Some(borrow.kind), |kind, var_span| { use crate::session_diagnostics::CaptureVarCause::*; let place = &borrow.borrowed_place; let desc_place = self.describe_any_place(place.as_ref()); @@ -1043,7 +1053,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "mutably borrow", ); borrow_spans.var_subdiag( - None, + self.dcx(), &mut err, Some(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture }), |kind, var_span| { @@ -1131,22 +1141,31 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; if issued_spans == borrow_spans { - borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| { - use crate::session_diagnostics::CaptureVarCause::*; - match kind { - hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine { - place: desc_place, - var_span, - is_single_var: false, - }, - hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => { - BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: false } + borrow_spans.var_subdiag( + self.dcx(), + &mut err, + Some(gen_borrow_kind), + |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + hir::ClosureKind::Coroutine(_) => BorrowUsePlaceCoroutine { + place: desc_place, + var_span, + is_single_var: false, + }, + hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => { + BorrowUsePlaceClosure { + place: desc_place, + var_span, + is_single_var: false, + } + } } - } - }); + }, + ); } else { issued_spans.var_subdiag( - Some(self.dcx()), + self.dcx(), &mut err, Some(issued_borrow.kind), |kind, var_span| { @@ -1165,7 +1184,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); borrow_spans.var_subdiag( - Some(self.dcx()), + self.dcx(), &mut err, Some(gen_borrow_kind), |kind, var_span| { @@ -2217,7 +2236,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label(borrow_span, "borrowed value does not live long enough"); err.span_label(drop_span, format!("`{name}` dropped here while still borrowed")); - borrow_spans.args_subdiag(&mut err, |args_span| { + borrow_spans.args_subdiag(self.dcx(), &mut err, |args_span| { crate::session_diagnostics::CaptureArgLabel::Capture { is_within: borrow_spans.for_coroutine(), args_span, @@ -2476,7 +2495,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None, ); - borrow_spans.args_subdiag(&mut err, |args_span| { + borrow_spans.args_subdiag(self.dcx(), &mut err, |args_span| { crate::session_diagnostics::CaptureArgLabel::Capture { is_within: borrow_spans.for_coroutine(), args_span, @@ -2935,7 +2954,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "assign", ); - loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| { + loan_spans.var_subdiag(self.dcx(), &mut err, Some(loan.kind), |kind, var_span| { use crate::session_diagnostics::CaptureVarCause::*; match kind { hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span }, @@ -2953,7 +2972,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place); - loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| { + loan_spans.var_subdiag(self.dcx(), &mut err, Some(loan.kind), |kind, var_span| { use crate::session_diagnostics::CaptureVarCause::*; match kind { hir::ClosureKind::Coroutine(_) => BorrowUseInCoroutine { var_span }, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 59f3aa706edea..4ca854c857de9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -124,7 +124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() { let did = did.expect_local(); if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) { - diag.eager_subdiagnostic( + diag.subdiagnostic( self.dcx(), OnClosureNote::InvokedTwice { place_name: &ty::place_to_string_for_capture( @@ -146,7 +146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() { let did = did.expect_local(); if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) { - diag.eager_subdiagnostic( + diag.subdiagnostic( self.dcx(), OnClosureNote::MovedTwice { place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place), @@ -587,11 +587,12 @@ impl UseSpans<'_> { /// Add a span label to the arguments of the closure, if it exists. pub(super) fn args_subdiag( self, + dcx: &rustc_errors::DiagCtxt, err: &mut Diagnostic, f: impl FnOnce(Span) -> CaptureArgLabel, ) { if let UseSpans::ClosureUse { args_span, .. } = self { - err.subdiagnostic(f(args_span)); + err.subdiagnostic(dcx, f(args_span)); } } @@ -599,6 +600,7 @@ impl UseSpans<'_> { /// only adds label to the `path_span` pub(super) fn var_path_only_subdiag( self, + dcx: &rustc_errors::DiagCtxt, err: &mut Diagnostic, action: crate::InitializationRequiringAction, ) { @@ -607,20 +609,26 @@ impl UseSpans<'_> { if let UseSpans::ClosureUse { closure_kind, path_span, .. } = self { match closure_kind { hir::ClosureKind::Coroutine(_) => { - err.subdiagnostic(match action { - Borrow => BorrowInCoroutine { path_span }, - MatchOn | Use => UseInCoroutine { path_span }, - Assignment => AssignInCoroutine { path_span }, - PartialAssignment => AssignPartInCoroutine { path_span }, - }); + err.subdiagnostic( + dcx, + match action { + Borrow => BorrowInCoroutine { path_span }, + MatchOn | Use => UseInCoroutine { path_span }, + Assignment => AssignInCoroutine { path_span }, + PartialAssignment => AssignPartInCoroutine { path_span }, + }, + ); } hir::ClosureKind::Closure | hir::ClosureKind::CoroutineClosure(_) => { - err.subdiagnostic(match action { - Borrow => BorrowInClosure { path_span }, - MatchOn | Use => UseInClosure { path_span }, - Assignment => AssignInClosure { path_span }, - PartialAssignment => AssignPartInClosure { path_span }, - }); + err.subdiagnostic( + dcx, + match action { + Borrow => BorrowInClosure { path_span }, + MatchOn | Use => UseInClosure { path_span }, + Assignment => AssignInClosure { path_span }, + PartialAssignment => AssignPartInClosure { path_span }, + }, + ); } } } @@ -629,32 +637,32 @@ impl UseSpans<'_> { /// Add a subdiagnostic to the use of the captured variable, if it exists. pub(super) fn var_subdiag( self, - dcx: Option<&rustc_errors::DiagCtxt>, + dcx: &rustc_errors::DiagCtxt, err: &mut Diagnostic, kind: Option, f: impl FnOnce(hir::ClosureKind, Span) -> CaptureVarCause, ) { if let UseSpans::ClosureUse { closure_kind, capture_kind_span, path_span, .. } = self { if capture_kind_span != path_span { - err.subdiagnostic(match kind { - Some(kd) => match kd { - rustc_middle::mir::BorrowKind::Shared - | rustc_middle::mir::BorrowKind::Fake => { - CaptureVarKind::Immut { kind_span: capture_kind_span } - } + err.subdiagnostic( + dcx, + match kind { + Some(kd) => match kd { + rustc_middle::mir::BorrowKind::Shared + | rustc_middle::mir::BorrowKind::Fake => { + CaptureVarKind::Immut { kind_span: capture_kind_span } + } - rustc_middle::mir::BorrowKind::Mut { .. } => { - CaptureVarKind::Mut { kind_span: capture_kind_span } - } + rustc_middle::mir::BorrowKind::Mut { .. } => { + CaptureVarKind::Mut { kind_span: capture_kind_span } + } + }, + None => CaptureVarKind::Move { kind_span: capture_kind_span }, }, - None => CaptureVarKind::Move { kind_span: capture_kind_span }, - }); + ); }; let diag = f(closure_kind, path_span); - match dcx { - Some(hd) => err.eager_subdiagnostic(hd, diag), - None => err.subdiagnostic(diag), - }; + err.subdiagnostic(dcx, diag); } } @@ -1025,26 +1033,33 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { CallKind::FnCall { fn_trait_id, .. } if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() => { - err.subdiagnostic(CaptureReasonLabel::Call { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); - err.subdiagnostic(CaptureReasonNote::FnOnceMoveInCall { var_span }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::Call { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }, + ); + err.subdiagnostic(self.dcx(), CaptureReasonNote::FnOnceMoveInCall { var_span }); } CallKind::Operator { self_arg, .. } => { let self_arg = self_arg.unwrap(); - err.subdiagnostic(CaptureReasonLabel::OperatorUse { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::OperatorUse { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }, + ); if self.fn_self_span_reported.insert(fn_span) { - err.subdiagnostic(CaptureReasonNote::LhsMoveByOperator { - span: self_arg.span, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonNote::LhsMoveByOperator { span: self_arg.span }, + ); } } CallKind::Normal { self_arg, desugaring, method_did, method_args } => { @@ -1061,11 +1076,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); let func = tcx.def_path_str(method_did); - err.subdiagnostic(CaptureReasonNote::FuncTakeSelf { - func, - place_name: place_name.clone(), - span: self_arg.span, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonNote::FuncTakeSelf { + func, + place_name: place_name.clone(), + span: self_arg.span, + }, + ); } let parent_did = tcx.parent(method_did); let parent_self_ty = @@ -1079,7 +1097,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result)) }); if is_option_or_result && maybe_reinitialized_locations_is_empty { - err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::BorrowContent { var_span }, + ); } if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { let ty = moved_place.ty(self.body, tcx).ty; @@ -1093,18 +1114,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { _ => false, }; if suggest { - err.subdiagnostic(CaptureReasonSuggest::IterateSlice { - ty, - span: move_span.shrink_to_lo(), - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonSuggest::IterateSlice { + ty, + span: move_span.shrink_to_lo(), + }, + ); } - err.subdiagnostic(CaptureReasonLabel::ImplicitCall { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::ImplicitCall { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }, + ); // If the moved place was a `&mut` ref, then we can // suggest to reborrow it where it was moved, so it // will still be valid by the time we get to the usage. @@ -1128,19 +1155,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { if let Some((CallDesugaringKind::Await, _)) = desugaring { - err.subdiagnostic(CaptureReasonLabel::Await { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::Await { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }, + ); } else { - err.subdiagnostic(CaptureReasonLabel::MethodCall { - fn_call_span, - place_name: &place_name, - is_partial, - is_loop_message, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::MethodCall { + fn_call_span, + place_name: &place_name, + is_partial, + is_loop_message, + }, + ); } // Erase and shadow everything that could be passed to the new infcx. let ty = moved_place.ty(self.body, tcx).ty; @@ -1155,7 +1188,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) && self.infcx.can_eq(self.param_env, ty, self_ty) { - err.eager_subdiagnostic( + err.subdiagnostic( self.dcx(), CaptureReasonSuggest::FreshReborrow { span: move_span.shrink_to_hi(), @@ -1239,17 +1272,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { if move_span != span || is_loop_message { - err.subdiagnostic(CaptureReasonLabel::MovedHere { - move_span, - is_partial, - is_move_msg, - is_loop_message, - }); + err.subdiagnostic( + self.dcx(), + CaptureReasonLabel::MovedHere { + move_span, + is_partial, + is_move_msg, + is_loop_message, + }, + ); } // If the move error occurs due to a loop, don't show // another message for the same span if !is_loop_message { - move_spans.var_subdiag(None, err, None, |kind, var_span| match kind { + move_spans.var_subdiag(self.dcx(), err, None, |kind, var_span| match kind { hir::ClosureKind::Coroutine(_) => { CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial } } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 126a50c91b494..dad20690d02cc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -448,12 +448,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { None => "value".to_string(), }; - err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { - is_partial_move: false, - ty: place_ty, - place: &place_desc, - span, - }); + err.subdiagnostic( + self.dcx(), + crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move: false, + ty: place_ty, + place: &place_desc, + span, + }, + ); } else { binds_to.sort(); binds_to.dedup(); @@ -475,14 +478,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Some(desc) => format!("`{desc}`"), None => "value".to_string(), }; - err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { - is_partial_move: false, - ty: place_ty, - place: &place_desc, - span, - }); + err.subdiagnostic( + self.dcx(), + crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move: false, + ty: place_ty, + place: &place_desc, + span, + }, + ); - use_spans.args_subdiag(err, |args_span| { + use_spans.args_subdiag(self.dcx(), err, |args_span| { crate::session_diagnostics::CaptureArgLabel::MoveOutPlace { place: place_desc, args_span, @@ -580,12 +586,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if binds_to.len() == 1 { let place_desc = &format!("`{}`", self.local_names[*local].unwrap()); - err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { - is_partial_move: false, - ty: bind_to.ty, - place: place_desc, - span: binding_span, - }); + err.subdiagnostic( + self.dcx(), + crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move: false, + ty: bind_to.ty, + place: place_desc, + span: binding_span, + }, + ); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index b3d684086c286..5e659a5f3c239 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -229,7 +229,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } if suggest { borrow_spans.var_subdiag( - None, + self.dcx(), &mut err, Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }), |_kind, var_span| { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 7529ec53a9869..e8effd5c1633a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -616,13 +616,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap(); let upvar_def_span = self.infcx.tcx.hir().span(def_hir); let upvar_span = upvars_map.get(&def_hir).unwrap().span; - diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span }); - diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span }); + diag.subdiagnostic(self.dcx(), VarHereDenote::Defined { span: upvar_def_span }); + diag.subdiagnostic(self.dcx(), VarHereDenote::Captured { span: upvar_span }); } } if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() { - diag.subdiagnostic(VarHereDenote::FnMutInferred { span: fr_span }); + diag.subdiagnostic(self.dcx(), VarHereDenote::FnMutInferred { span: fr_span }); } self.suggest_move_on_borrowing_closure(&mut diag); @@ -788,7 +788,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, }; - diag.subdiagnostic(err_category); + diag.subdiagnostic(self.dcx(), err_category); self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); @@ -979,7 +979,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s `'static` requirement", ); - err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span }); + err.subdiagnostic(self.dcx(), RequireStaticErr::UsedImpl { multi_span }); err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs index cc0fbe46dcc11..79eb4406b8a33 100644 --- a/compiler/rustc_codegen_gcc/src/errors.rs +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -122,7 +122,7 @@ impl IntoDiagnostic<'_, G> for TargetFeatureDisableOrEnabl diag.span(span); }; if let Some(missing_features) = self.missing_features { - diag.subdiagnostic(missing_features); + diag.subdiagnostic(dcx, missing_features); } diag.arg("features", self.features.join(", ")); diag diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 587c5e9e8d235..87e3774068bcd 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -131,7 +131,7 @@ impl IntoDiagnostic<'_, G> for TargetFeatureDisableOrEnabl diag.span(span); }; if let Some(missing_features) = self.missing_features { - diag.subdiagnostic(missing_features); + diag.subdiagnostic(dcx, missing_features); } diag.arg("features", self.features.join(", ")); diag diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 0c93cfaa54647..25ddd5e85f9f3 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -131,7 +131,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { // FIXME(effects) revisit this if !tcx.is_const_trait_impl_raw(data.impl_def_id) { let span = tcx.def_span(data.impl_def_id); - err.subdiagnostic(errors::NonConstImplNote { span }); + err.subdiagnostic(tcx.dcx(), errors::NonConstImplNote { span }); } } } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index a1abe8fd4f306..f91b6655f6399 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -263,14 +263,10 @@ pub enum SubdiagnosticMessage { /// Translatable message which has already been translated eagerly. /// /// Some diagnostics have repeated subdiagnostics where the same interpolated variables would - /// be instantiated multiple times with different values. As translation normally happens - /// immediately prior to emission, after the diagnostic and subdiagnostic derive logic has run, - /// the setting of diagnostic arguments in the derived code will overwrite previous variable - /// values and only the final value will be set when translation occurs - resulting in - /// incorrect diagnostics. Eager translation results in translation for a subdiagnostic - /// happening immediately after the subdiagnostic derive's logic has been run. This variant - /// stores messages which have been translated eagerly. - Eager(Cow<'static, str>), + /// be instantiated multiple times with different values. These subdiagnostics' messages + /// are translated when they are added to the parent diagnostic, producing this variant of + /// `DiagnosticMessage`. + Translated(Cow<'static, str>), /// Identifier of a Fluent message. Instances of this variant are generated by the /// `Subdiagnostic` derive. FluentIdentifier(FluentId), @@ -307,19 +303,15 @@ impl From> for SubdiagnosticMessage { pub enum DiagnosticMessage { /// Non-translatable diagnostic message. Str(Cow<'static, str>), - /// Translatable message which has already been translated eagerly. + /// Translatable message which has been already translated. /// /// Some diagnostics have repeated subdiagnostics where the same interpolated variables would - /// be instantiated multiple times with different values. As translation normally happens - /// immediately prior to emission, after the diagnostic and subdiagnostic derive logic has run, - /// the setting of diagnostic arguments in the derived code will overwrite previous variable - /// values and only the final value will be set when translation occurs - resulting in - /// incorrect diagnostics. Eager translation results in translation for a subdiagnostic - /// happening immediately after the subdiagnostic derive's logic has been run. This variant - /// stores messages which have been translated eagerly. - Eager(Cow<'static, str>), + /// be instantiated multiple times with different values. These subdiagnostics' messages + /// are translated when they are added to the parent diagnostic, producing this variant of + /// `DiagnosticMessage`. + Translated(Cow<'static, str>), /// Identifier for a Fluent message (with optional attribute) corresponding to the diagnostic - /// message. + /// message. Yet to be translated. /// /// /// @@ -336,7 +328,7 @@ impl DiagnosticMessage { pub fn with_subdiagnostic_message(&self, sub: SubdiagnosticMessage) -> Self { let attr = match sub { SubdiagnosticMessage::Str(s) => return DiagnosticMessage::Str(s), - SubdiagnosticMessage::Eager(s) => return DiagnosticMessage::Eager(s), + SubdiagnosticMessage::Translated(s) => return DiagnosticMessage::Translated(s), SubdiagnosticMessage::FluentIdentifier(id) => { return DiagnosticMessage::FluentIdentifier(id, None); } @@ -345,7 +337,7 @@ impl DiagnosticMessage { match self { DiagnosticMessage::Str(s) => DiagnosticMessage::Str(s.clone()), - DiagnosticMessage::Eager(s) => DiagnosticMessage::Eager(s.clone()), + DiagnosticMessage::Translated(s) => DiagnosticMessage::Translated(s.clone()), DiagnosticMessage::FluentIdentifier(id, _) => { DiagnosticMessage::FluentIdentifier(id.clone(), Some(attr)) } @@ -354,7 +346,7 @@ impl DiagnosticMessage { pub fn as_str(&self) -> Option<&str> { match self { - DiagnosticMessage::Eager(s) | DiagnosticMessage::Str(s) => Some(s), + DiagnosticMessage::Translated(s) | DiagnosticMessage::Str(s) => Some(s), DiagnosticMessage::FluentIdentifier(_, _) => None, } } @@ -396,7 +388,7 @@ impl Into for DiagnosticMessage { fn into(self) -> SubdiagnosticMessage { match self { DiagnosticMessage::Str(s) => SubdiagnosticMessage::Str(s), - DiagnosticMessage::Eager(s) => SubdiagnosticMessage::Eager(s), + DiagnosticMessage::Translated(s) => SubdiagnosticMessage::Translated(s), DiagnosticMessage::FluentIdentifier(id, None) => { SubdiagnosticMessage::FluentIdentifier(id) } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index b14a12175c79b..d31321b48d007 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -851,18 +851,11 @@ impl Diagnostic { self } - /// Add a subdiagnostic from a type that implements `Subdiagnostic` (see - /// [rustc_macros::Subdiagnostic]). - pub fn subdiagnostic(&mut self, subdiagnostic: impl AddToDiagnostic) -> &mut Self { - subdiagnostic.add_to_diagnostic(self); - self - } - /// Add a subdiagnostic from a type that implements `Subdiagnostic` (see /// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages /// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of /// interpolated variables). - pub fn eager_subdiagnostic( + pub fn subdiagnostic( &mut self, dcx: &crate::DiagCtxt, subdiagnostic: impl AddToDiagnostic, @@ -921,7 +914,7 @@ impl Diagnostic { /// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by /// combining it with the primary message of the diagnostic (if translatable, otherwise it just /// passes the user's string along). - fn subdiagnostic_message_to_diagnostic_message( + pub(crate) fn subdiagnostic_message_to_diagnostic_message( &self, attr: impl Into, ) -> DiagnosticMessage { diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index e484bef0e0bc9..0572df69ca947 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -404,9 +404,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { name: impl Into>, arg: impl IntoDiagnosticArg, )); forward!((subdiagnostic, with_subdiagnostic)( - subdiagnostic: impl crate::AddToDiagnostic, - )); - forward!((eager_subdiagnostic, with_eager_subdiagnostic)( dcx: &DiagCtxt, subdiagnostic: impl crate::AddToDiagnostic, )); diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 38c6661377b19..00b7c50ad17d3 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -10,6 +10,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::{FileLines, FileName, SourceFile, Span}; +use crate::error::TranslateError; use crate::snippet::{ Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString, }; @@ -559,6 +560,18 @@ pub struct SilentEmitter { pub fatal_note: String, } +pub fn silent_translate<'a>( + message: &'a DiagnosticMessage, +) -> Result, TranslateError<'_>> { + match message { + DiagnosticMessage::Str(msg) | DiagnosticMessage::Translated(msg) => Ok(Cow::Borrowed(msg)), + DiagnosticMessage::FluentIdentifier(identifier, _) => { + // Any value works here. + Ok(identifier.clone()) + } + } +} + impl Translate for SilentEmitter { fn fluent_bundle(&self) -> Option<&Lrc> { None @@ -567,6 +580,16 @@ impl Translate for SilentEmitter { fn fallback_fluent_bundle(&self) -> &FluentBundle { panic!("silent emitter attempted to translate message") } + + // Override `translate_message` for the silent emitter because eager translation of + // subdiagnostics result in a call to this. + fn translate_message<'a>( + &'a self, + message: &'a DiagnosticMessage, + _: &'a FluentArgs<'_>, + ) -> Result, TranslateError<'_>> { + silent_translate(message) + } } impl Emitter for SilentEmitter { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b738ecb54ffc1..986e87cd2e2ce 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -640,7 +640,8 @@ impl DiagCtxt { message: DiagnosticMessage, args: impl Iterator>, ) -> SubdiagnosticMessage { - SubdiagnosticMessage::Eager(Cow::from(self.eagerly_translate_to_string(message, args))) + let inner = self.inner.borrow(); + inner.eagerly_translate(message, args) } /// Translate `message` eagerly with `args` to `String`. @@ -650,8 +651,7 @@ impl DiagCtxt { args: impl Iterator>, ) -> String { let inner = self.inner.borrow(); - let args = crate::translation::to_fluent_args(args); - inner.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string() + inner.eagerly_translate_to_string(message, args) } // This is here to not allow mutation of flags; @@ -1446,6 +1446,25 @@ impl DiagCtxtInner { .or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied()) } + /// Translate `message` eagerly with `args` to `SubdiagnosticMessage::Eager`. + pub fn eagerly_translate<'a>( + &self, + message: DiagnosticMessage, + args: impl Iterator>, + ) -> SubdiagnosticMessage { + SubdiagnosticMessage::Translated(Cow::from(self.eagerly_translate_to_string(message, args))) + } + + /// Translate `message` eagerly with `args` to `String`. + pub fn eagerly_translate_to_string<'a>( + &self, + message: DiagnosticMessage, + args: impl Iterator>, + ) -> String { + let args = crate::translation::to_fluent_args(args); + self.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string() + } + fn flush_delayed(&mut self) { if self.delayed_bugs.is_empty() { return; @@ -1484,15 +1503,22 @@ impl DiagCtxtInner { } let mut bug = - if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner }; + if backtrace || self.ice_file.is_none() { bug.decorate(self) } else { bug.inner }; // "Undelay" the delayed bugs (into plain `Bug`s). if bug.level != DelayedBug { // NOTE(eddyb) not panicking here because we're already producing // an ICE, and the more information the merrier. - bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel { + let subdiag = InvalidFlushedDelayedDiagnosticLevel { span: bug.span.primary_span().unwrap(), level: bug.level, + }; + // FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it + // just uses `DiagCtxtInner` functions. + subdiag.add_to_diagnostic_with(&mut bug, |diag, msg| { + let args = diag.args(); + let msg = diag.subdiagnostic_message_to_diagnostic_message(msg); + self.eagerly_translate(msg, args) }); } bug.level = Bug; @@ -1527,25 +1553,35 @@ impl DelayedDiagnostic { DelayedDiagnostic { inner: diagnostic, note: backtrace } } - fn decorate(mut self) -> Diagnostic { + fn decorate(mut self, dcx: &DiagCtxtInner) -> Diagnostic { + // FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it + // just uses `DiagCtxtInner` functions. + let subdiag_with = |diag: &mut Diagnostic, msg| { + let args = diag.args(); + let msg = diag.subdiagnostic_message_to_diagnostic_message(msg); + dcx.eagerly_translate(msg, args) + }; + match self.note.status() { BacktraceStatus::Captured => { let inner = &self.inner; - self.inner.subdiagnostic(DelayedAtWithNewline { + let subdiag = DelayedAtWithNewline { span: inner.span.primary_span().unwrap_or(DUMMY_SP), emitted_at: inner.emitted_at.clone(), note: self.note, - }); + }; + subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with); } // Avoid the needless newline when no backtrace has been captured, // the display impl should just be a single line. _ => { let inner = &self.inner; - self.inner.subdiagnostic(DelayedAtWithoutNewline { + let subdiag = DelayedAtWithoutNewline { span: inner.span.primary_span().unwrap_or(DUMMY_SP), emitted_at: inner.emitted_at.clone(), note: self.note, - }); + }; + subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with); } } @@ -1691,15 +1727,15 @@ impl Level { } // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite. -pub fn add_elided_lifetime_in_path_suggestion( +pub fn add_elided_lifetime_in_path_suggestion( source_map: &SourceMap, - diag: &mut Diagnostic, + diag: &mut DiagnosticBuilder<'_, E>, n: usize, path_span: Span, incl_angl_brckt: bool, insertion_span: Span, ) { - diag.subdiagnostic(ExpectedLifetimeParameter { span: path_span, count: n }); + diag.subdiagnostic(diag.dcx, ExpectedLifetimeParameter { span: path_span, count: n }); if !source_map.is_span_accessible(insertion_span) { // Do not try to suggest anything if generated by a proc-macro. return; @@ -1708,11 +1744,10 @@ pub fn add_elided_lifetime_in_path_suggestion( let suggestion = if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") }; - diag.subdiagnostic(IndicateAnonymousLifetime { - span: insertion_span.shrink_to_hi(), - count: n, - suggestion, - }); + diag.subdiagnostic( + diag.dcx, + IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion }, + ); } pub fn report_ambiguity_error<'a, G: EmissionGuarantee>( diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 5bdac367d55e7..5f074dbbbad30 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -2,7 +2,7 @@ use crate::error::{TranslateError, TranslateErrorKind}; use crate::snippet::Style; use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle}; use rustc_data_structures::sync::Lrc; -use rustc_error_messages::FluentArgs; +pub use rustc_error_messages::FluentArgs; use std::borrow::Cow; use std::env; use std::error::Report; @@ -61,7 +61,7 @@ pub trait Translate { ) -> Result, TranslateError<'_>> { trace!(?message, ?args); let (identifier, attr) = match message { - DiagnosticMessage::Str(msg) | DiagnosticMessage::Eager(msg) => { + DiagnosticMessage::Str(msg) | DiagnosticMessage::Translated(msg) => { return Ok(Cow::Borrowed(msg)); } DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr), diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index eec86c36aedae..b3d370a9c8dec 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -7,7 +7,7 @@ use crate::mbe::{ use rustc_ast::token::{self, Token, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage}; +use rustc_errors::{Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, DiagnosticMessage}; use rustc_parse::parser::{Parser, Recovery}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::Ident; @@ -58,7 +58,7 @@ pub(super) fn failed_to_match_macro<'cx>( err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro"); } - annotate_doc_comment(&mut err, sess.source_map(), span); + annotate_doc_comment(cx.sess.dcx(), &mut err, sess.source_map(), span); if let Some(span) = remaining_matcher.span() { err.span_note(span, format!("while trying to match {remaining_matcher}")); @@ -311,12 +311,17 @@ enum ExplainDocComment { }, } -pub(super) fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) { +pub(super) fn annotate_doc_comment( + dcx: &DiagCtxt, + err: &mut Diagnostic, + sm: &SourceMap, + span: Span, +) { if let Ok(src) = sm.span_to_snippet(span) { if src.starts_with("///") || src.starts_with("/**") { - err.subdiagnostic(ExplainDocComment::Outer { span }); + err.subdiagnostic(dcx, ExplainDocComment::Outer { span }); } else if src.starts_with("//!") || src.starts_with("/*!") { - err.subdiagnostic(ExplainDocComment::Inner { span }); + err.subdiagnostic(dcx, ExplainDocComment::Inner { span }); } } } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 83e0f870c8a25..c82609503c18a 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -454,7 +454,7 @@ pub fn compile_declarative_macro( let sp = token.span.substitute_dummy(def.span); let mut err = sess.dcx().struct_span_err(sp, s); err.span_label(sp, msg); - annotate_doc_comment(&mut err, sess.source_map(), sp); + annotate_doc_comment(sess.dcx(), &mut err, sess.source_map(), sp); err.emit(); return dummy_syn_ext(); } diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 0311aa94cd485..f4ac010691cd4 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -261,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let semi = expr.span.shrink_to_hi().with_hi(semi_span.hi()); let sugg = crate::errors::RemoveSemiForCoerce { expr: expr.span, ret, semi }; - diag.subdiagnostic(sugg); + diag.subdiagnostic(self.dcx(), sugg); } /// When the previously checked expression (the scrutinee) diverges, diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f21de1609cb7f..2142bb914209a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -993,19 +993,25 @@ impl<'a, 'tcx> CastCheck<'tcx> { if let Some((deref_ty, _)) = derefed { // Give a note about what the expr derefs to. if deref_ty != self.expr_ty.peel_refs() { - err.subdiagnostic(errors::DerefImplsIsEmpty { - span: self.expr_span, - deref_ty: fcx.ty_to_string(deref_ty), - }); + err.subdiagnostic( + fcx.dcx(), + errors::DerefImplsIsEmpty { + span: self.expr_span, + deref_ty: fcx.ty_to_string(deref_ty), + }, + ); } // Create a multipart suggestion: add `!` and `.is_empty()` in // place of the cast. - err.subdiagnostic(errors::UseIsEmpty { - lo: self.expr_span.shrink_to_lo(), - hi: self.span.with_lo(self.expr_span.hi()), - expr_ty: fcx.ty_to_string(self.expr_ty), - }); + err.subdiagnostic( + fcx.dcx(), + errors::UseIsEmpty { + lo: self.expr_span.shrink_to_lo(), + hi: self.span.with_lo(self.expr_span.hi()), + expr_ty: fcx.ty_to_string(self.expr_ty), + }, + ); } } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 19bdeab409bb7..7f30b36a1f94a 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -395,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(sp) = tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp)); } oprnd_t = Ty::new_error(tcx, err.emit()); } @@ -2050,7 +2050,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .shrink_to_hi() .to(range_end.span); - err.subdiagnostic(TypeMismatchFruTypo { expr_span: range_start.span, fru_span, expr }); + err.subdiagnostic( + self.dcx(), + TypeMismatchFruTypo { expr_span: range_start.span, fru_span, expr }, + ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 65b8505c09098..339bc9f0f7a99 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1269,7 +1269,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // The user provided `ptr::null()`, but the function expects // `ptr::null_mut()`. - err.subdiagnostic(SuggestPtrNullMut { span: arg.span }); + err.subdiagnostic(self.dcx(), SuggestPtrNullMut { span: arg.span }); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 8b6f263b1a746..c1a32a1afa3cf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -458,13 +458,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // but those checks need to be a bit more delicate and the benefit is diminishing. if self.can_eq(self.param_env, found_ty_inner, peeled) && error_tys_equate_as_ref { let sugg = prefix_wrap(".as_ref()"); - err.subdiagnostic(errors::SuggestConvertViaMethod { - span: expr.span.shrink_to_hi(), - sugg, - expected, - found, - borrow_removal_span, - }); + err.subdiagnostic( + self.dcx(), + errors::SuggestConvertViaMethod { + span: expr.span.shrink_to_hi(), + sugg, + expected, + found, + borrow_removal_span, + }, + ); return true; } else if let Some((deref_ty, _)) = self.autoderef(expr.span, found_ty_inner).silence_errors().nth(1) @@ -472,13 +475,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && error_tys_equate_as_ref { let sugg = prefix_wrap(".as_deref()"); - err.subdiagnostic(errors::SuggestConvertViaMethod { - span: expr.span.shrink_to_hi(), - sugg, - expected, - found, - borrow_removal_span, - }); + err.subdiagnostic( + self.dcx(), + errors::SuggestConvertViaMethod { + span: expr.span.shrink_to_hi(), + sugg, + expected, + found, + borrow_removal_span, + }, + ); return true; } else if let ty::Adt(adt, _) = found_ty_inner.peel_refs().kind() && Some(adt.did()) == self.tcx.lang_items().string() @@ -565,7 +571,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { end: span.shrink_to_hi(), }, }; - err.subdiagnostic(suggest_boxing); + err.subdiagnostic(self.dcx(), suggest_boxing); true } else { @@ -799,29 +805,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &fn_decl.output { &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() && !can_suggest => { // `fn main()` must return `()`, do not suggest changing return type - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Unit { span }); + err.subdiagnostic(self.dcx(), errors::ExpectedReturnTypeLabel::Unit { span }); return true; } &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() => { if let Some(found) = found.make_suggestable(self.tcx, false) { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { - span, - found: found.to_string(), - }); + err.subdiagnostic( + self.dcx(), + errors::AddReturnTypeSuggestion::Add { span, found: found.to_string() }, + ); return true; } else if let ty::Closure(_, args) = found.kind() // FIXME(compiler-errors): Get better at printing binders... && let closure = args.as_closure() && closure.sig().is_suggestable(self.tcx, false) { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { - span, - found: closure.print_as_impl_trait().to_string(), - }); + err.subdiagnostic( + self.dcx(), + errors::AddReturnTypeSuggestion::Add { + span, + found: closure.print_as_impl_trait().to_string(), + }, + ); return true; } else { // FIXME: if `found` could be `impl Iterator` we should suggest that. - err.subdiagnostic(errors::AddReturnTypeSuggestion::MissingHere { span }); + err.subdiagnostic( + self.dcx(), + errors::AddReturnTypeSuggestion::MissingHere { span }, + ); return true; } } @@ -843,16 +855,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?found); if found.is_suggestable(self.tcx, false) { if term.span.is_empty() { - err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { - span: term.span, - found: found.to_string(), - }); + err.subdiagnostic( + self.dcx(), + errors::AddReturnTypeSuggestion::Add { + span: term.span, + found: found.to_string(), + }, + ); return true; } else { - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { - span: term.span, - expected, - }); + err.subdiagnostic( + self.dcx(), + errors::ExpectedReturnTypeLabel::Other { + span: term.span, + expected, + }, + ); } } } else { @@ -867,10 +885,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.normalize(hir_ty.span, ty); let ty = self.tcx.instantiate_bound_regions_with_erased(ty); if self.can_coerce(expected, ty) { - err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { - span: hir_ty.span, - expected, - }); + err.subdiagnostic( + self.dcx(), + errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected }, + ); self.try_suggest_return_impl_trait(err, expected, ty, fn_id); return true; } @@ -1106,7 +1124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sp = self.tcx.sess.source_map().start_point(expr.span).with_parent(None); if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }` - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp)); true } else { false @@ -1220,7 +1238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { return false; }; - diag.subdiagnostic(subdiag); + diag.subdiagnostic(self.dcx(), subdiag); return true; } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 729ce1f00cd8b..2269e9f7d4c3d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3173,19 +3173,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if impls_trait(trait_info.def_id) { self.suggest_valid_traits(err, vec![trait_info.def_id], false); } else { - err.subdiagnostic(CandidateTraitNote { - span: self.tcx.def_span(trait_info.def_id), - trait_name: self.tcx.def_path_str(trait_info.def_id), - item_name, - action_or_ty: if trait_missing_method { - "NONE".to_string() - } else { - param_type.map_or_else( - || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented. - ToString::to_string, - ) + err.subdiagnostic( + self.dcx(), + CandidateTraitNote { + span: self.tcx.def_span(trait_info.def_id), + trait_name: self.tcx.def_path_str(trait_info.def_id), + item_name, + action_or_ty: if trait_missing_method { + "NONE".to_string() + } else { + param_type.map_or_else( + || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented. + ToString::to_string, + ) + }, }, - }); + ); } } trait_infos => { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 9a8444e6a2bcd..929b3557f5242 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -824,7 +824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the previous expression was a block expression, suggest parentheses // (turning this into a binary subtraction operation instead.) // for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs) - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp)); } else { match actual.kind() { Uint(_) if op == hir::UnOp::Neg => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b953b25d6c4cf..280701b8ec6d5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -846,7 +846,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { arm_ty, arm_span, ) { - err.subdiagnostic(subdiag); + err.subdiagnostic(self.dcx(), subdiag); } if let hir::Node::Expr(m) = self.tcx.parent_hir_node(scrut_hir_id) && let hir::Node::Stmt(stmt) = self.tcx.parent_hir_node(m.hir_id) @@ -892,7 +892,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { else_ty, else_span, ) { - err.subdiagnostic(subdiag); + err.subdiagnostic(self.dcx(), subdiag); } // don't suggest wrapping either blocks in `if .. {} else {}` let is_empty_arm = |id| { diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 02200d6a4aaf5..50ac6235debc0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -342,7 +342,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { trait_predicates: trait_predicates.join(", "), } }; - err.subdiagnostic(suggestion); + err.subdiagnostic(self.dcx(), suggestion); } pub(super) fn report_placeholder_failure( diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 248e1c0fcc878..31e980fdfabe3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -84,7 +84,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { start_sp: return_sp.with_hi(return_sp.lo() + BytePos(4)), end_sp: return_sp.shrink_to_hi(), }; - err.subdiagnostic(sugg); + err.subdiagnostic(self.dcx(), sugg); let mut starts = Vec::new(); let mut ends = Vec::new(); @@ -93,7 +93,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ends.push(span.shrink_to_hi()); } let sugg = SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }; - err.subdiagnostic(sugg); + err.subdiagnostic(self.dcx(), sugg); } pub(super) fn suggest_tuple_pattern( @@ -138,7 +138,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span_low: cause.span.shrink_to_lo(), span_high: cause.span.shrink_to_hi(), }; - diag.subdiagnostic(sugg); + diag.subdiagnostic(self.dcx(), sugg); } _ => { // More than one matching variant. @@ -147,7 +147,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause_span: cause.span, compatible_variants, }; - diag.subdiagnostic(sugg); + diag.subdiagnostic(self.dcx(), sugg); } } } @@ -219,9 +219,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }, (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { // FIXME: Seems like we can't have a suggestion and a note with different spans in a single subdiagnostic - diag.subdiagnostic(ConsiderAddingAwait::FutureSugg { - span: exp_span.shrink_to_hi(), - }); + diag.subdiagnostic( + self.dcx(), + ConsiderAddingAwait::FutureSugg { span: exp_span.shrink_to_hi() }, + ); Some(ConsiderAddingAwait::FutureSuggNote { span: exp_span }) } (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() @@ -246,7 +247,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _ => None, }; if let Some(subdiag) = subdiag { - diag.subdiagnostic(subdiag); + diag.subdiagnostic(self.dcx(), subdiag); } } @@ -282,7 +283,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } else { return; }; - diag.subdiagnostic(suggestion); + diag.subdiagnostic(self.dcx(), suggestion); } } } @@ -322,15 +323,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (true, false) => FunctionPointerSuggestion::UseRef { span, fn_name }, (false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name }, (true, true) => { - diag.subdiagnostic(FnItemsAreDistinct); + diag.subdiagnostic(self.dcx(), FnItemsAreDistinct); FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig } } (false, false) => { - diag.subdiagnostic(FnItemsAreDistinct); + diag.subdiagnostic(self.dcx(), FnItemsAreDistinct); FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig } } }; - diag.subdiagnostic(sugg); + diag.subdiagnostic(self.dcx(), sugg); } (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => { let expected_sig = @@ -339,7 +340,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).instantiate(self.tcx, args2)); if self.same_type_modulo_infer(*expected_sig, *found_sig) { - diag.subdiagnostic(FnUniqTypes); + diag.subdiagnostic(self.dcx(), FnUniqTypes); } if !self.same_type_modulo_infer(*found_sig, *expected_sig) @@ -368,7 +369,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } }; - diag.subdiagnostic(sug); + diag.subdiagnostic(self.dcx(), sug); } (ty::FnDef(did, args), ty::FnPtr(sig)) => { let expected_sig = @@ -387,7 +388,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { format!("{fn_name} as {found_sig}") }; - diag.subdiagnostic(FnConsiderCasting { casting }); + diag.subdiagnostic(self.dcx(), FnConsiderCasting { casting }); } _ => { return; @@ -819,7 +820,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let diag = self.consider_returning_binding_diag(blk, expected_ty); match diag { Some(diag) => { - err.subdiagnostic(diag); + err.subdiagnostic(self.dcx(), diag); true } None => false, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 7445e2e80b407..2987d8a5ed0b2 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1758,7 +1758,7 @@ impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> { diag.note(note.to_string()); } if let Some(sugg) = self.suggestion { - diag.subdiagnostic(sugg); + diag.subdiagnostic(diag.dcx, sugg); } } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 85bb9584a0575..ae481efb263df 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -331,44 +331,7 @@ impl DiagnosticDeriveVariantBuilder { } } (Meta::Path(_), "subdiagnostic") => { - if FieldInnerTy::from_type(&info.binding.ast().ty).will_iterate() { - let DiagnosticDeriveKind::Diagnostic = self.kind else { - // No eager translation for lints. - return Ok(quote! { diag.subdiagnostic(#binding); }); - }; - return Ok(quote! { diag.eager_subdiagnostic(dcx, #binding); }); - } else { - return Ok(quote! { diag.subdiagnostic(#binding); }); - } - } - (Meta::List(meta_list), "subdiagnostic") => { - let err = || { - span_err( - meta_list.span().unwrap(), - "`eager` is the only supported nested attribute for `subdiagnostic`", - ) - .emit(); - }; - - let Ok(p): Result = meta_list.parse_args() else { - err(); - return Ok(quote! {}); - }; - - if !p.is_ident("eager") { - err(); - return Ok(quote! {}); - } - - match &self.kind { - DiagnosticDeriveKind::Diagnostic => {} - DiagnosticDeriveKind::LintDiagnostic => { - throw_invalid_attr!(attr, |diag| { - diag.help("eager subdiagnostics are not supported on lints") - }) - } - }; - return Ok(quote! { diag.eager_subdiagnostic(dcx, #binding); }); + return Ok(quote! { diag.subdiagnostic(diag.dcx, #binding); }); } _ => (), } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 692f4511bb807..a0235f20a0570 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1109,7 +1109,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some()); if !is_empty_match && all_arms_have_guards { - err.subdiagnostic(NonExhaustiveMatchAllArmsGuarded); + err.subdiagnostic(cx.tcx.dcx(), NonExhaustiveMatchAllArmsGuarded); } if let Some((span, sugg)) = suggestion { err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders); diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 30de40e226c33..ff4918df9a262 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -270,7 +270,7 @@ impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.span_label(self.yield_sp, fluent::_subdiag::label); if let Some(reason) = self.reason { - diag.subdiagnostic(reason); + diag.subdiagnostic(diag.dcx, reason); } diag.span_help(self.src_sp, fluent::_subdiag::help); diag.arg("pre", self.pre); diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 445d5b2ce790c..e44c63f1ed760 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2350,7 +2350,7 @@ impl<'a> Parser<'a> { let mut err = self.dcx().struct_span_err(span, msg); let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp)); } err.span_label(span, "expected expression"); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1a57474bac289..06134818435ca 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1433,7 +1433,7 @@ impl<'a> Parser<'a> { // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }` // then suggest parens around the lhs. if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&lo) { - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + err.subdiagnostic(this.dcx(), ExprParenthesesNeeded::surrounding(*sp)); } err }) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 8050b34956ce9..a34adbe7f674d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1917,7 +1917,7 @@ impl<'a> Parser<'a> { if self.token.kind == token::Not { if let Err(mut err) = self.unexpected::() { // Encounter the macro invocation - err.subdiagnostic(MacroExpandsToAdtField { adt_ty }); + err.subdiagnostic(self.dcx(), MacroExpandsToAdtField { adt_ty }); return Err(err); } } @@ -2336,10 +2336,13 @@ impl<'a> Parser<'a> { .into_iter() .any(|s| self.prev_token.is_ident_named(s)); - err.subdiagnostic(errors::FnTraitMissingParen { - span: self.prev_token.span, - machine_applicable, - }); + err.subdiagnostic( + self.dcx(), + errors::FnTraitMissingParen { + span: self.prev_token.span, + machine_applicable, + }, + ); } return Err(err); } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 12260ec95a5b9..75fc013d3e6fe 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -843,7 +843,7 @@ impl<'a> Parser<'a> { let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { - err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + err.subdiagnostic(self.dcx(), ExprParenthesesNeeded::surrounding(*sp)); } Err(err) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d91a865e38aba..737481c78db68 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -403,9 +403,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if let Some(suggestion) = suggestion { - err.subdiagnostic(ChangeImportBindingSuggestion { span: binding_span, suggestion }); + err.subdiagnostic( + self.dcx(), + ChangeImportBindingSuggestion { span: binding_span, suggestion }, + ); } else { - err.subdiagnostic(ChangeImportBinding { span: binding_span }); + err.subdiagnostic(self.dcx(), ChangeImportBinding { span: binding_span }); } } @@ -1430,17 +1433,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules { - err.subdiagnostic(MaybeMissingMacroRulesName { span: ident.span }); + err.subdiagnostic(self.dcx(), MaybeMissingMacroRulesName { span: ident.span }); return; } if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { - err.subdiagnostic(ExplicitUnsafeTraits { span: ident.span, ident }); + err.subdiagnostic(self.dcx(), ExplicitUnsafeTraits { span: ident.span, ident }); return; } if self.macro_names.contains(&ident.normalize_to_macros_2_0()) { - err.subdiagnostic(AddedMacroUse); + err.subdiagnostic(self.dcx(), AddedMacroUse); return; } @@ -1450,10 +1453,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let span = self.def_span(def_id); let source_map = self.tcx.sess.source_map(); let head_span = source_map.guess_head_span(span); - err.subdiagnostic(ConsiderAddingADerive { - span: head_span.shrink_to_lo(), - suggestion: "#[derive(Default)]\n".to_string(), - }); + err.subdiagnostic( + self.dcx(), + ConsiderAddingADerive { + span: head_span.shrink_to_lo(), + suggestion: "#[derive(Default)]\n".to_string(), + }, + ); } for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] { if let Ok(binding) = self.early_resolve_ident_in_lexical_scope( diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 30fb35238c3c7..dcd01b9b33417 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1262,12 +1262,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // exclude decl_macro if self.get_macro_by_def_id(def_id).macro_rules => { - err.subdiagnostic(ConsiderAddingMacroExport { + err.subdiagnostic(self.dcx(), ConsiderAddingMacroExport { span: binding.span, }); } _ => { - err.subdiagnostic(ConsiderMarkingAsPub { + err.subdiagnostic(self.dcx(), ConsiderMarkingAsPub { span: import.span, ident, }); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 5d712461993d8..7f0d8374b3abc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1095,11 +1095,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { Side::Start => (segment.ident.span.between(range.span), " @ ".into()), Side::End => (range.span.to(segment.ident.span), format!("{} @ ..", segment.ident)), }; - err.subdiagnostic(errors::UnexpectedResUseAtOpInSlicePatWithRangeSugg { - span, - ident: segment.ident, - snippet, - }); + err.subdiagnostic( + self.r.dcx(), + errors::UnexpectedResUseAtOpInSlicePatWithRangeSugg { + span, + ident: segment.ident, + snippet, + }, + ); } enum Side { @@ -1191,10 +1194,13 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }); if let Some(param) = param { - err.subdiagnostic(errors::UnexpectedResChangeTyToConstParamSugg { - span: param.shrink_to_lo(), - applicability, - }); + err.subdiagnostic( + self.r.dcx(), + errors::UnexpectedResChangeTyToConstParamSugg { + span: param.shrink_to_lo(), + applicability, + }, + ); } } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 8adb0cbcc9d76..a906d5532b5a0 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -173,21 +173,21 @@ pub fn add_feature_diagnostics_for_issue( feature_from_cli: bool, ) { if let Some(n) = find_feature_issue(feature, issue) { - err.subdiagnostic(FeatureDiagnosticForIssue { n }); + err.subdiagnostic(sess.dcx(), FeatureDiagnosticForIssue { n }); } // #23973: do not suggest `#![feature(...)]` if we are in beta/stable if sess.parse_sess.unstable_features.is_nightly_build() { if feature_from_cli { - err.subdiagnostic(CliFeatureDiagnosticHelp { feature }); + err.subdiagnostic(sess.dcx(), CliFeatureDiagnosticHelp { feature }); } else { - err.subdiagnostic(FeatureDiagnosticHelp { feature }); + err.subdiagnostic(sess.dcx(), FeatureDiagnosticHelp { feature }); } if sess.opts.unstable_opts.ui_testing { - err.subdiagnostic(SuggestUpgradeCompiler::ui_testing()); + err.subdiagnostic(sess.dcx(), SuggestUpgradeCompiler::ui_testing()); } else if let Some(suggestion) = SuggestUpgradeCompiler::new() { - err.subdiagnostic(suggestion); + err.subdiagnostic(sess.dcx(), suggestion); } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index c7b56aac7e55b..a8b6fc1f12c26 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4830,11 +4830,14 @@ fn hint_missing_borrow<'tcx>( } if !to_borrow.is_empty() { - err.subdiagnostic(errors::AdjustSignatureBorrow::Borrow { to_borrow }); + err.subdiagnostic(infcx.dcx(), errors::AdjustSignatureBorrow::Borrow { to_borrow }); } if !remove_borrow.is_empty() { - err.subdiagnostic(errors::AdjustSignatureBorrow::RemoveBorrow { remove_borrow }); + err.subdiagnostic( + infcx.dcx(), + errors::AdjustSignatureBorrow::RemoveBorrow { remove_borrow }, + ); } } diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 7f91af59d5622..ed401d5751b69 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -504,7 +504,7 @@ pub fn report_msg<'tcx>( let is_local = machine.is_local(frame_info); // No span for non-local frames and the first frame (which is the error site). if is_local && idx > 0 { - err.eager_subdiagnostic(err.dcx, frame_info.as_note(machine.tcx)); + err.subdiagnostic(err.dcx, frame_info.as_note(machine.tcx)); } else { let sm = sess.source_map(); let span = sm.span_to_embeddable_string(frame_info.span); diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index f0af401d3da4b..cff025cf2ab3a 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; @@ -40,6 +41,16 @@ impl Translate for SilentEmitter { fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { panic!("silent emitter attempted to translate a diagnostic"); } + + // Override `translate_message` for the silent emitter because eager translation of + // subdiagnostics result in a call to this. + fn translate_message<'a>( + &'a self, + message: &'a rustc_errors::DiagnosticMessage, + _: &'a rustc_errors::translation::FluentArgs<'_>, + ) -> Result, rustc_errors::error::TranslateError<'_>> { + rustc_errors::emitter::silent_translate(message) + } } impl Emitter for SilentEmitter { diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index d3cfd28082d61..6cc6fdfc0eb2b 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -701,7 +701,7 @@ struct RawIdentDiagnosticArg { #[diag(no_crate_example)] struct SubdiagnosticBad { #[subdiagnostic(bad)] - //~^ ERROR `eager` is the only supported nested attribute for `subdiagnostic` + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -717,7 +717,7 @@ struct SubdiagnosticBadStr { #[diag(no_crate_example)] struct SubdiagnosticBadTwice { #[subdiagnostic(bad, bad)] - //~^ ERROR `eager` is the only supported nested attribute for `subdiagnostic` + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -725,7 +725,7 @@ struct SubdiagnosticBadTwice { #[diag(no_crate_example)] struct SubdiagnosticBadLitStr { #[subdiagnostic("bad")] - //~^ ERROR `eager` is the only supported nested attribute for `subdiagnostic` + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -739,8 +739,9 @@ struct SubdiagnosticEagerLint { #[derive(Diagnostic)] #[diag(no_crate_example)] -struct SubdiagnosticEagerCorrect { +struct SubdiagnosticEagerFormerlyCorrect { #[subdiagnostic(eager)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -761,6 +762,7 @@ pub(crate) struct SubdiagnosticWithSuggestion { #[diag(no_crate_example)] struct SubdiagnosticEagerSuggestion { #[subdiagnostic(eager)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute sub: SubdiagnosticWithSuggestion, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 2032b8a972a3b..f2dbc718c7627 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -468,11 +468,11 @@ LL | #[label] | = help: `#[label]` and `#[suggestion]` can only be applied to fields -error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:703:7 +error: `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:703:5 | LL | #[subdiagnostic(bad)] - | ^^^^^^^^^^^^^ + | ^ error: `#[subdiagnostic = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:711:5 @@ -480,40 +480,50 @@ error: `#[subdiagnostic = ...]` is not a valid attribute LL | #[subdiagnostic = "bad"] | ^ -error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:719:7 +error: `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:719:5 | LL | #[subdiagnostic(bad, bad)] - | ^^^^^^^^^^^^^ + | ^ -error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:727:7 +error: `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:727:5 | LL | #[subdiagnostic("bad")] - | ^^^^^^^^^^^^^ + | ^ error: `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:735:5 | LL | #[subdiagnostic(eager)] | ^ + +error: `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:743:5 | - = help: eager subdiagnostics are not supported on lints +LL | #[subdiagnostic(eager)] + | ^ + +error: `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:764:5 + | +LL | #[subdiagnostic(eager)] + | ^ error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:793:23 + --> $DIR/diagnostic-derive.rs:795:23 | LL | #[suggestion(code())] | ^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:801:23 + --> $DIR/diagnostic-derive.rs:803:23 | LL | #[suggestion(code(foo))] | ^^^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:825:5 + --> $DIR/diagnostic-derive.rs:827:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^ @@ -529,13 +539,13 @@ LL | #[diag = "E0123"] | ^ maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/diagnostic-derive.rs:801:23 + --> $DIR/diagnostic-derive.rs:803:23 | LL | #[suggestion(code(foo))] | ^^^ maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/diagnostic-derive.rs:810:25 + --> $DIR/diagnostic-derive.rs:812:25 | LL | #[suggestion(code = 3)] | ^ maybe a missing crate `core`? @@ -601,7 +611,7 @@ LL | #[diag(nonsense, code = E0123)] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:807:10 + --> $DIR/diagnostic-derive.rs:809:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -622,7 +632,7 @@ note: required by a bound in `DiagnosticBuilder::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC = note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 84 previous errors +error: aborting due to 86 previous errors Some errors have detailed explanations: E0277, E0425, E0433. For more information about an error, try `rustc --explain E0277`. From 7c2db703b0b56cede3d8ce264e9d1fcdb1397f94 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 11 Feb 2024 17:18:57 -0500 Subject: [PATCH 05/10] Don't use mem::zeroed in vec::IntoIter --- library/alloc/src/vec/into_iter.rs | 63 ++++++++++++++---------------- tests/codegen/vec-iter.rs | 17 +++++++- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 63d8fe19ac35c..dfd42ca06193a 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -11,7 +11,7 @@ use core::iter::{ TrustedRandomAccessNoCoerce, }; use core::marker::PhantomData; -use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; +use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::num::NonZero; #[cfg(not(no_global_oom_handling))] use core::ops::Deref; @@ -200,27 +200,23 @@ impl Iterator for IntoIter { #[inline] fn next(&mut self) -> Option { - if T::IS_ZST { - if self.ptr.as_ptr() == self.end as *mut _ { - None - } else { - // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by - // reducing the `end`. - self.end = self.end.wrapping_byte_sub(1); - - // Make up a value of this ZST. - Some(unsafe { mem::zeroed() }) + let ptr = if T::IS_ZST { + if self.ptr.as_ptr() == self.end as *mut T { + return None; } + // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by + // reducing the `end`. + self.end = self.end.wrapping_byte_sub(1); + self.ptr } else { if self.ptr == non_null!(self.end, T) { - None - } else { - let old = self.ptr; - self.ptr = unsafe { old.add(1) }; - - Some(unsafe { ptr::read(old.as_ptr()) }) + return None; } - } + let old = self.ptr; + self.ptr = unsafe { old.add(1) }; + old + }; + Some(unsafe { ptr.read() }) } #[inline] @@ -305,7 +301,7 @@ impl Iterator for IntoIter { // Also note the implementation of `Self: TrustedRandomAccess` requires // that `T: Copy` so reading elements from the buffer doesn't invalidate // them for `Drop`. - unsafe { if T::IS_ZST { mem::zeroed() } else { self.ptr.add(i).read() } } + unsafe { self.ptr.add(i).read() } } } @@ -314,23 +310,22 @@ impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { if T::IS_ZST { - if self.end as *mut _ == self.ptr.as_ptr() { - None - } else { - // See above for why 'ptr.offset' isn't used - self.end = self.end.wrapping_byte_sub(1); - - // Make up a value of this ZST. - Some(unsafe { mem::zeroed() }) + if self.ptr.as_ptr() == self.end as *mut _ { + return None; } + // See above for why 'ptr.offset' isn't used + self.end = self.end.wrapping_byte_sub(1); + // Note that even though this is next_back() we're reading from `self.ptr`, not + // `self.end`. We track our length using the byte offset from `self.ptr` to `self.end`, + // so the end pointer may not be suitably aligned for T. + Some(unsafe { ptr::read(self.ptr.as_ptr()) }) } else { - if non_null!(self.end, T) == self.ptr { - None - } else { - let new_end = unsafe { non_null!(self.end, T).sub(1) }; - *non_null!(mut self.end, T) = new_end; - - Some(unsafe { ptr::read(new_end.as_ptr()) }) + if self.ptr == non_null!(self.end, T) { + return None; + } + unsafe { + self.end = self.end.sub(1); + Some(ptr::read(self.end)) } } } diff --git a/tests/codegen/vec-iter.rs b/tests/codegen/vec-iter.rs index 0282791e9d169..4e2068587510c 100644 --- a/tests/codegen/vec-iter.rs +++ b/tests/codegen/vec-iter.rs @@ -32,9 +32,9 @@ pub fn vec_iter_is_empty_nonnull(it: &vec::IntoIter) -> bool { it.is_empty() } -// CHECK-LABEL: @vec_iter_next +// CHECK-LABEL: @vec_iter_next_nonnull #[no_mangle] -pub fn vec_iter_next(it: &mut vec::IntoIter) -> Option { +pub fn vec_iter_next_nonnull(it: &mut vec::IntoIter) -> Option { // CHECK: load ptr // CHECK-SAME: !nonnull // CHECK-SAME: !noundef @@ -44,3 +44,16 @@ pub fn vec_iter_next(it: &mut vec::IntoIter) -> Option { // CHECK: ret it.next() } + +// CHECK-LABEL: @vec_iter_next_back_nonnull +#[no_mangle] +pub fn vec_iter_next_back_nonnull(it: &mut vec::IntoIter) -> Option { + // CHECK: load ptr + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: load ptr + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: ret + it.next_back() +} From ede99234c48c120b909990ee2ee51dd87cfed6f5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sat, 17 Feb 2024 10:51:35 +1100 Subject: [PATCH 06/10] Make `CodegenBackend::join_codegen` infallible. Because they all are, in practice. --- compiler/rustc_codegen_cranelift/src/lib.rs | 6 +++--- compiler/rustc_codegen_gcc/src/lib.rs | 8 +++----- compiler/rustc_codegen_llvm/src/lib.rs | 4 ++-- compiler/rustc_codegen_ssa/src/traits/backend.rs | 2 +- compiler/rustc_interface/src/queries.rs | 2 +- .../hotplug_codegen_backend/the_backend.rs | 4 ++-- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 7c432e9c59051..7e2e1f7c6ac07 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -233,11 +233,11 @@ impl CodegenBackend for CraneliftCodegenBackend { ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames, - ) -> Result<(CodegenResults, FxIndexMap), ErrorGuaranteed> { - Ok(ongoing_codegen + ) -> (CodegenResults, FxIndexMap) { + ongoing_codegen .downcast::() .unwrap() - .join(sess, self.config.borrow().as_ref().unwrap())) + .join(sess, self.config.borrow().as_ref().unwrap()) } fn link( diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 863b6333bcc29..09ce059476ec7 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -217,13 +217,11 @@ impl CodegenBackend for GccCodegenBackend { Box::new(res) } - fn join_codegen(&self, ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames) -> Result<(CodegenResults, FxIndexMap), ErrorGuaranteed> { - let (codegen_results, work_products) = ongoing_codegen + fn join_codegen(&self, ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames) -> (CodegenResults, FxIndexMap) { + ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") - .join(sess); - - Ok((codegen_results, work_products)) + .join(sess) } fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) -> Result<(), ErrorGuaranteed> { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e688e84db61a5..35210b0b2e86d 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -369,7 +369,7 @@ impl CodegenBackend for LlvmCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> Result<(CodegenResults, FxIndexMap), ErrorGuaranteed> { + ) -> (CodegenResults, FxIndexMap) { let (codegen_results, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") @@ -382,7 +382,7 @@ impl CodegenBackend for LlvmCodegenBackend { }); } - Ok((codegen_results, work_products)) + (codegen_results, work_products) } fn link( diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 8e9907ed8bb03..cb1feff13363e 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -102,7 +102,7 @@ pub trait CodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> Result<(CodegenResults, FxIndexMap), ErrorGuaranteed>; + ) -> (CodegenResults, FxIndexMap); /// This is called on the returned `CodegenResults` from `join_codegen` fn link( diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 2a4eefb7f771b..211bcb9da94db 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -259,7 +259,7 @@ pub struct Linker { impl Linker { pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) -> Result<()> { let (codegen_results, work_products) = - codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames)?; + codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames); sess.compile_status()?; diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 9e0a7ba63d05f..28a1e27cccccd 100644 --- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -49,11 +49,11 @@ impl CodegenBackend for TheBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, - ) -> Result<(CodegenResults, FxIndexMap), ErrorGuaranteed> { + ) -> (CodegenResults, FxIndexMap) { let codegen_results = ongoing_codegen .downcast::() .expect("in join_codegen: ongoing_codegen is not a CodegenResults"); - Ok((*codegen_results, FxIndexMap::default())) + (*codegen_results, FxIndexMap::default()) } fn link( From 228441dbd6e9fc823da545ed29499f6f8e5d7101 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 16 Feb 2024 17:56:15 +0000 Subject: [PATCH 07/10] Use fulfillment in next trait solver coherence --- .../src/solve/inspect/analyse.rs | 8 ++- .../src/traits/coherence.rs | 70 ++++++++++--------- tests/ui/coherence/coherent-due-to-fulfill.rs | 20 ++++++ .../incoherent-even-though-we-fulfill.rs | 22 ++++++ .../incoherent-even-though-we-fulfill.stderr | 14 ++++ 5 files changed, 97 insertions(+), 37 deletions(-) create mode 100644 tests/ui/coherence/coherent-due-to-fulfill.rs create mode 100644 tests/ui/coherence/incoherent-even-though-we-fulfill.rs create mode 100644 tests/ui/coherence/incoherent-even-though-we-fulfill.stderr diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index f33d0f397ce9e..9020c11b2559e 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -230,8 +230,10 @@ impl<'tcx> ProofTreeInferCtxtExt<'tcx> for InferCtxt<'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, visitor: &mut V, ) -> ControlFlow { - let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); - let proof_tree = proof_tree.unwrap(); - visitor.visit_goal(&InspectGoal::new(self, 0, &proof_tree)) + self.probe(|_| { + let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); + let proof_tree = proof_tree.unwrap(); + visitor.visit_goal(&InspectGoal::new(self, 0, &proof_tree)) + }) } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index e48bd437f59c5..f663f02f87289 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -8,23 +8,21 @@ use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::InferOk; use crate::regions::InferCtxtRegionExt; use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor}; -use crate::solve::{deeply_normalize_for_diagnostics, inspect}; -use crate::traits::engine::TraitEngineExt; -use crate::traits::query::evaluate_obligation::InferCtxtExt; +use crate::solve::{deeply_normalize_for_diagnostics, inspect, FulfillmentCtxt}; +use crate::traits::engine::TraitEngineExt as _; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::structural_normalize::StructurallyNormalizeExt; use crate::traits::NormalizeExt; use crate::traits::SkipLeakCheck; use crate::traits::{ - Obligation, ObligationCause, ObligationCtxt, PredicateObligation, PredicateObligations, - SelectionContext, + Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext, }; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; -use rustc_infer::traits::{util, TraitEngine}; +use rustc_infer::traits::{util, TraitEngine, TraitEngineExt}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_middle::traits::specialization_graph::OverlapMode; @@ -310,29 +308,35 @@ fn equate_impl_headers<'tcx>( fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligations: &'a [PredicateObligation<'tcx>], -) -> Option<&'a PredicateObligation<'tcx>> { +) -> Option> { let infcx = selcx.infcx; - obligations.iter().find(|obligation| { - let evaluation_result = if infcx.next_trait_solver() { - infcx.evaluate_obligation(obligation) - } else { + if infcx.next_trait_solver() { + let mut fulfill_cx = FulfillmentCtxt::new(infcx); + fulfill_cx.register_predicate_obligations(infcx, obligations.iter().cloned()); + + // We only care about the obligations that are *definitely* true errors. + // Ambiguities do not prove the disjointness of two impls. + let mut errors = fulfill_cx.select_where_possible(infcx); + errors.pop().map(|err| err.obligation) + } else { + obligations.iter().cloned().find(|obligation| { // We use `evaluate_root_obligation` to correctly track intercrate // ambiguity clauses. We cannot use this in the new solver. - selcx.evaluate_root_obligation(obligation) - }; - - match evaluation_result { - Ok(result) => !result.may_apply(), - // If overflow occurs, we need to conservatively treat the goal as possibly holding, - // since there can be instantiations of this goal that don't overflow and result in - // success. This isn't much of a problem in the old solver, since we treat overflow - // fatally (this still can be encountered: ), - // but in the new solver, this is very important for correctness, since overflow - // *must* be treated as ambiguity for completeness. - Err(_overflow) => false, - } - }) + let evaluation_result = selcx.evaluate_root_obligation(obligation); + + match evaluation_result { + Ok(result) => !result.may_apply(), + // If overflow occurs, we need to conservatively treat the goal as possibly holding, + // since there can be instantiations of this goal that don't overflow and result in + // success. This isn't much of a problem in the old solver, since we treat overflow + // fatally (this still can be encountered: ), + // but in the new solver, this is very important for correctness, since overflow + // *must* be treated as ambiguity for completeness. + Err(_overflow) => false, + } + }) + } } /// Check if both impls can be satisfied by a common type by considering whether @@ -522,15 +526,13 @@ fn try_prove_negated_where_clause<'tcx>( // Without this, we over-eagerly register coherence ambiguity candidates when // impl candidates do exist. let ref infcx = root_infcx.fork_with_intercrate(false); - let ocx = ObligationCtxt::new(infcx); - - ocx.register_obligation(Obligation::new( - infcx.tcx, - ObligationCause::dummy(), - param_env, - negative_predicate, - )); - if !ocx.select_all_or_error().is_empty() { + let mut fulfill_cx = FulfillmentCtxt::new(infcx); + + fulfill_cx.register_predicate_obligation( + infcx, + Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, negative_predicate), + ); + if !fulfill_cx.select_all_or_error(infcx).is_empty() { return false; } diff --git a/tests/ui/coherence/coherent-due-to-fulfill.rs b/tests/ui/coherence/coherent-due-to-fulfill.rs new file mode 100644 index 0000000000000..084f9be0a8c3f --- /dev/null +++ b/tests/ui/coherence/coherent-due-to-fulfill.rs @@ -0,0 +1,20 @@ +//@ compile-flags: -Znext-solver=coherence +//@ check-pass + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +trait Foo {} +trait Bar {} + +// self type starts out as `?0` but is constrained to `()` +// due to the where clause below. Because `(): Bar` does not +// hold in intercrate mode, we can prove the impls disjoint. +impl Foo for T where (): Mirror {} +impl Foo for T where T: Bar {} + +fn main() {} diff --git a/tests/ui/coherence/incoherent-even-though-we-fulfill.rs b/tests/ui/coherence/incoherent-even-though-we-fulfill.rs new file mode 100644 index 0000000000000..b3c9cf328c21c --- /dev/null +++ b/tests/ui/coherence/incoherent-even-though-we-fulfill.rs @@ -0,0 +1,22 @@ +//@ compile-flags: -Znext-solver=coherence + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +trait Foo {} + +// Even though using fulfillment in coherence allows us to figure out that +// `?T = ()`, we still treat it as incoherent because `(): Iterator` may be +// added upstream. +impl Foo for T where (): Mirror {} +//~^ NOTE first implementation here +impl Foo for T where T: Iterator {} +//~^ ERROR conflicting implementations of trait `Foo` for type `()` +//~| NOTE conflicting implementation for `()` +//~| NOTE upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions + +fn main() {} diff --git a/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr b/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr new file mode 100644 index 0000000000000..b16465d201140 --- /dev/null +++ b/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `()` + --> $DIR/incoherent-even-though-we-fulfill.rs:17:1 + | +LL | impl Foo for T where (): Mirror {} + | --------------------------------------------- first implementation here +LL | +LL | impl Foo for T where T: Iterator {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + | + = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. From dae22a598bc28fd03522fcba5d09150ca53cdc4f Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 17 Feb 2024 01:15:08 +0100 Subject: [PATCH 08/10] Fix `cfg(target_abi = "sim")` on i386-apple-ios i386-apple-ios is also a simulator target --- compiler/rustc_target/src/spec/base/apple/mod.rs | 15 ++++++++------- .../src/spec/targets/i386_apple_ios.rs | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index afd60b40c3be1..460e7e034f3a8 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -17,6 +17,7 @@ pub enum Arch { Arm64e, Arm64_32, I386, + I386_sim, I686, X86_64, X86_64h, @@ -34,7 +35,7 @@ impl Arch { Arm64 | Arm64_macabi | Arm64_sim => "arm64", Arm64e => "arm64e", Arm64_32 => "arm64_32", - I386 => "i386", + I386 | I386_sim => "i386", I686 => "i686", X86_64 | X86_64_sim | X86_64_macabi => "x86_64", X86_64h => "x86_64h", @@ -45,7 +46,7 @@ impl Arch { Cow::Borrowed(match self { Armv7k | Armv7s => "arm", Arm64 | Arm64e | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", - I386 | I686 => "x86", + I386 | I386_sim | I686 => "x86", X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", }) } @@ -56,7 +57,7 @@ impl Arch { X86_64_macabi | Arm64_macabi => "macabi", // x86_64-apple-ios is a simulator target, even though it isn't // declared that way in the target like the other ones... - Arm64_sim | X86_64_sim => "sim", + I386_sim | Arm64_sim | X86_64_sim => "sim", } } @@ -70,7 +71,7 @@ impl Arch { // Only macOS 10.12+ is supported, which means // all x86_64/x86 CPUs must be running at least penryn // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82 - I386 | I686 => "penryn", + I386 | I386_sim | I686 => "penryn", X86_64 | X86_64_sim => "penryn", X86_64_macabi => "penryn", // Note: `core-avx2` is slightly more advanced than `x86_64h`, see @@ -85,7 +86,7 @@ impl Arch { fn stack_probes(self) -> StackProbeType { match self { Armv7k | Armv7s => StackProbeType::None, - Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h | X86_64_sim + Arm64 | Arm64e | Arm64_32 | I386 | I386_sim | I686 | X86_64 | X86_64h | X86_64_sim | X86_64_macabi | Arm64_macabi | Arm64_sim => StackProbeType::Inline, } } @@ -302,8 +303,8 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> // Otherwise if cross-compiling for a different OS/SDK, remove any part // of the linking environment that's wrong and reversed. match arch { - Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim - | X86_64h | Arm64_sim => { + Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I386_sim | I686 | X86_64 + | X86_64_sim | X86_64h | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index a221538b9022f..63133ff99ea4a 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -2,7 +2,7 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::I386; + let arch = Arch::I386_sim; Target { // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. From d80198595c926949a84944220a8176940a32654b Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 17 Feb 2024 01:16:11 +0100 Subject: [PATCH 09/10] Fix comment --- compiler/rustc_target/src/spec/base/apple/mod.rs | 2 -- compiler/rustc_target/src/spec/targets/i386_apple_ios.rs | 2 ++ compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs | 2 ++ compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 460e7e034f3a8..aee5d60626e31 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -55,8 +55,6 @@ impl Arch { match self { Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", X86_64_macabi | Arm64_macabi => "macabi", - // x86_64-apple-ios is a simulator target, even though it isn't - // declared that way in the target like the other ones... I386_sim | Arm64_sim | X86_64_sim => "sim", } } diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index 63133ff99ea4a..d78acdbd1aad5 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -2,6 +2,8 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + // i386-apple-ios is a simulator target, even though it isn't declared + // that way in the target name like the other ones... let arch = Arch::I386_sim; Target { // Clang automatically chooses a more specific target based on diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs index 55165ea4ec68c..5b34390141e0e 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs @@ -2,6 +2,8 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { + // x86_64-apple-ios is a simulator target, even though it isn't declared + // that way in the target name like the other ones... let arch = Arch::X86_64_sim; let mut base = opts("ios", arch); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs index 20b0161255314..95033699f1af3 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs @@ -2,6 +2,8 @@ use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + // x86_64-apple-tvos is a simulator target, even though it isn't declared + // that way in the target name like the other ones... let arch = Arch::X86_64_sim; Target { llvm_target: tvos_sim_llvm_target(arch).into(), From 3ec7d0a57c3bf82877b4a40e25a8f55cfb6e94fa Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 17 Feb 2024 13:19:01 +0300 Subject: [PATCH 10/10] create stamp file for clippy in `Config::download_clippy` Due to missing stamp file, we were downloading (and applying nix patches if enabled) continuously every time `Config::download_clippy` was called. This change fixes that by creating stamp file at the end of the function. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/download.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index e63d60feff125..b4ae3578ce317 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -399,6 +399,7 @@ impl Config { self.fix_bin_or_dylib(&cargo_clippy.with_file_name(exe("clippy-driver", host))); } + self.create(&clippy_stamp, date); cargo_clippy }