diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 35b8de64af7ef..737e81eb6ecc0 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -23,7 +23,7 @@ macro_rules! gate { ($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{ if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) { feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain) - .help_mv($help) + .with_help($help) .emit(); } }}; diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs index 9882f1d23ce67..1059007428221 100644 --- a/compiler/rustc_ast_passes/src/show_span.rs +++ b/compiler/rustc_ast_passes/src/show_span.rs @@ -38,21 +38,21 @@ struct ShowSpanVisitor<'a> { impl<'a> Visitor<'a> for ShowSpanVisitor<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { if let Mode::Expression = self.mode { - self.dcx.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" }); + self.dcx.emit_warn(errors::ShowSpan { span: e.span, msg: "expression" }); } visit::walk_expr(self, e); } fn visit_pat(&mut self, p: &'a ast::Pat) { if let Mode::Pattern = self.mode { - self.dcx.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" }); + self.dcx.emit_warn(errors::ShowSpan { span: p.span, msg: "pattern" }); } visit::walk_pat(self, p); } fn visit_ty(&mut self, t: &'a ast::Ty) { if let Mode::Type = self.mode { - self.dcx.emit_warning(errors::ShowSpan { span: t.span, msg: "type" }); + self.dcx.emit_warn(errors::ShowSpan { span: t.span, msg: "type" }); } visit::walk_ty(self, t); } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 77678dcaba9e1..b3f601b75956c 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -621,7 +621,7 @@ pub fn eval_condition( } }; let Some(min_version) = parse_version(*min_version) else { - dcx.emit_warning(session_diagnostics::UnknownVersionLiteral { span: *span }); + dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span }); return false; }; diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 5f61a56c189ac..89606b81a9946 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -55,11 +55,11 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> { fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); DiagnosticBuilder::new(dcx, level, fluent::attr_unknown_meta_item) - .span_mv(self.span) - .code_mv(error_code!(E0541)) - .arg_mv("item", self.item) - .arg_mv("expected", expected.join(", ")) - .span_label_mv(self.span, fluent::attr_label) + .with_span(self.span) + .with_code(error_code!(E0541)) + .with_arg("item", self.item) + .with_arg("expected", expected.join(", ")) + .with_span_label(self.span, fluent::attr_label) } } diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index a9fc0a6f415da..351976cdaea6b 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{struct_span_err, DiagCtxt, DiagnosticBuilder}; +use rustc_errors::{struct_span_code_err, DiagCtxt, DiagnosticBuilder}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; @@ -31,15 +31,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrow_span: Span, borrow_desc: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0503, "cannot use {} because it was mutably borrowed", desc, ) - .span_label_mv(borrow_span, format!("{borrow_desc} is borrowed here")) - .span_label_mv(span, format!("use of borrowed {borrow_desc}")) + .with_span_label(borrow_span, format!("{borrow_desc} is borrowed here")) + .with_span_label(span, format!("use of borrowed {borrow_desc}")) } pub(crate) fn cannot_mutably_borrow_multiply( @@ -52,7 +52,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_load_end_span: Option, ) -> DiagnosticBuilder<'tcx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), new_loan_span, E0499, @@ -98,7 +98,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_loan_span: Span, old_load_end_span: Option, ) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), new_loan_span, E0524, @@ -131,7 +131,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_opt_via: &str, previous_end_span: Option, ) -> DiagnosticBuilder<'cx> { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), new_loan_span, E0500, @@ -163,7 +163,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { previous_end_span: Option, second_borrow_desc: &str, ) -> DiagnosticBuilder<'cx> { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), new_loan_span, E0501, @@ -196,7 +196,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { old_load_end_span: Option, ) -> DiagnosticBuilder<'cx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0502, @@ -236,15 +236,15 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { borrow_span: Span, desc: &str, ) -> DiagnosticBuilder<'cx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0506, "cannot assign to {} because it is borrowed", desc, ) - .span_label_mv(borrow_span, format!("{desc} is borrowed here")) - .span_label_mv(span, format!("{desc} is assigned to here but it was already borrowed")) + .with_span_label(borrow_span, format!("{desc} is borrowed here")) + .with_span_label(span, format!("{desc} is assigned to here but it was already borrowed")) } pub(crate) fn cannot_reassign_immutable( @@ -254,11 +254,11 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { is_arg: bool, ) -> DiagnosticBuilder<'cx> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; - struct_span_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) + struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) } pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'tcx> { - struct_span_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) + struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) } pub(crate) fn cannot_move_out_of( @@ -266,7 +266,13 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, move_from_desc: &str, ) -> DiagnosticBuilder<'cx> { - struct_span_err!(self.dcx(), move_from_span, E0507, "cannot move out of {}", move_from_desc) + struct_span_code_err!( + self.dcx(), + move_from_span, + E0507, + "cannot move out of {}", + move_from_desc + ) } /// Signal an error due to an attempt to move out of the interior @@ -283,7 +289,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { (&ty::Slice(_), _) => "slice", _ => span_bug!(move_from_span, "this path should not cause illegal move"), }; - struct_span_err!( + struct_span_code_err!( self.dcx(), move_from_span, E0508, @@ -291,7 +297,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { ty, type_name, ) - .span_label_mv(move_from_span, "cannot move out of here") + .with_span_label(move_from_span, "cannot move out of here") } pub(crate) fn cannot_move_out_of_interior_of_drop( @@ -299,14 +305,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, container_ty: Ty<'_>, ) -> DiagnosticBuilder<'cx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), move_from_span, E0509, "cannot move out of type `{}`, which implements the `Drop` trait", container_ty, ) - .span_label_mv(move_from_span, "cannot move out of here") + .with_span_label(move_from_span, "cannot move out of here") } pub(crate) fn cannot_act_on_moved_value( @@ -318,7 +324,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { ) -> DiagnosticBuilder<'tcx> { let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); - struct_span_err!( + struct_span_code_err!( self.dcx(), use_span, E0382, @@ -335,7 +341,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { path: &str, reason: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!(self.dcx(), span, E0596, "cannot borrow {} as mutable{}", path, reason) + struct_span_code_err!( + self.dcx(), + span, + E0596, + "cannot borrow {} as mutable{}", + path, + reason + ) } pub(crate) fn cannot_mutate_in_immutable_section( @@ -346,7 +359,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { immutable_section: &str, action: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), mutate_span, E0510, @@ -355,8 +368,8 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { immutable_place, immutable_section, ) - .span_label_mv(mutate_span, format!("cannot {action}")) - .span_label_mv(immutable_span, format!("value is immutable in {immutable_section}")) + .with_span_label(mutate_span, format!("cannot {action}")) + .with_span_label(immutable_span, format!("value is immutable in {immutable_section}")) } pub(crate) fn cannot_borrow_across_coroutine_yield( @@ -365,20 +378,20 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { yield_span: Span, ) -> DiagnosticBuilder<'tcx> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0626, "borrow may still be in use when {coroutine_kind:#} yields", ) - .span_label_mv(yield_span, "possible yield occurs here") + .with_span_label(yield_span, "possible yield occurs here") } pub(crate) fn cannot_borrow_across_destructor( &self, borrow_span: Span, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), borrow_span, E0713, @@ -391,7 +404,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { span: Span, path: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) + struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) } pub(crate) fn cannot_return_reference_to_local( @@ -401,7 +414,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { reference_desc: &str, path_desc: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0515, @@ -410,7 +423,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { REFERENCE = reference_desc, LOCAL = path_desc, ) - .span_label_mv( + .with_span_label( span, format!("{return_kind}s a {reference_desc} data owned by the current function"), ) @@ -424,22 +437,22 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { capture_span: Span, scope: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), closure_span, E0373, "{closure_kind} may outlive the current {scope}, but it borrows {borrowed_path}, \ which is owned by the current {scope}", ) - .span_label_mv(capture_span, format!("{borrowed_path} is borrowed here")) - .span_label_mv(closure_span, format!("may outlive borrowed value {borrowed_path}")) + .with_span_label(capture_span, format!("{borrowed_path} is borrowed here")) + .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) } pub(crate) fn thread_local_value_does_not_live_long_enough( &self, span: Span, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0712, @@ -451,7 +464,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { &self, span: Span, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) + struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) } } @@ -460,7 +473,7 @@ pub(crate) fn borrowed_data_escapes_closure<'tcx>( escape_span: Span, escapes_from: &str, ) -> DiagnosticBuilder<'tcx> { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), escape_span, E0521, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 5baa108ed3cce..b4a73574aa2e3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1,7 +1,9 @@ +// ignore-tidy-filelength + use either::Either; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; +use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; @@ -550,8 +552,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; let used = desired_action.as_general_verb_in_past_tense(); - let mut err = - struct_span_err!(self.dcx(), span, E0381, "{used} binding {desc}{isnt_initialized}"); + let mut err = struct_span_code_err!( + self.dcx(), + span, + E0381, + "{used} binding {desc}{isnt_initialized}" + ); use_spans.var_path_only_subdiag(&mut err, desired_action); if let InitializationRequiringAction::PartialAssignment @@ -2219,11 +2225,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); self.thread_local_value_does_not_live_long_enough(borrow_span) - .span_label_mv( + .with_span_label( borrow_span, "thread-local variables cannot be borrowed beyond the end of the function", ) - .span_label_mv(drop_span, "end of enclosing function is here") + .with_span_label(drop_span, "end of enclosing function is here") } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index f1e712d814a10..6606be2f9f42f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -315,7 +315,7 @@ impl<'tcx> BorrowExplanation<'tcx> { let mut failed = false; let elaborated_args = std::iter::zip(*args, &generics.params).map(|(arg, param)| { - if let Some(ty::Dynamic(obj, _, ty::DynKind::Dyn)) = arg.as_type().map(Ty::kind) { + if let Some(ty::Dynamic(obj, _, ty::Dyn)) = arg.as_type().map(Ty::kind) { let default = tcx.object_lifetime_default(param.def_id); let re_static = tcx.lifetimes.re_static; @@ -339,7 +339,7 @@ impl<'tcx> BorrowExplanation<'tcx> { has_dyn = true; - Ty::new_dynamic(tcx, obj, implied_region, ty::DynKind::Dyn).into() + Ty::new_dynamic(tcx, obj, implied_region, ty::Dyn).into() } else { arg } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 50dde5ce636e7..fb3525e8998c0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -334,9 +334,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { span, &format!("`{}` in pattern guard", self.local_names[local].unwrap()), ) - .note_mv( + .with_note( "variables bound in patterns cannot be moved from \ - until after the end of the pattern guard", + until after the end of the pattern guard", ); } else if decl.is_ref_to_static() { return self.report_cannot_move_from_static(move_place, span); @@ -382,8 +382,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); self.cannot_move_out_of(span, &place_description) - .span_label_mv(upvar_span, "captured outer variable") - .span_label_mv( + .with_span_label(upvar_span, "captured outer variable") + .with_span_label( self.infcx.tcx.def_span(def_id), format!("captured by this `{closure_kind}` closure"), ) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 020429c191449..8c8ca1ead400b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -27,7 +27,7 @@ use rustc_middle::ty::TypeVisitor; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{Region, TyCtxt}; use rustc_span::symbol::{kw, Ident}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use crate::borrowck_errors; use crate::session_diagnostics::{ @@ -84,7 +84,7 @@ impl<'tcx> RegionErrors<'tcx> { #[track_caller] pub fn push(&mut self, val: impl Into>) { let val = val.into(); - self.1.sess.dcx().span_delayed_bug(DUMMY_SP, format!("{val:?}")); + self.1.sess.dcx().delayed_bug(format!("{val:?}")); self.0.push(val); } pub fn is_empty(&self) -> bool { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 5f427a5ac801c..462b5c8da42c7 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -421,7 +421,7 @@ fn check_opaque_type_parameter_valid( return Err(tcx .dcx() .struct_span_err(span, "non-defining opaque type use in defining scope") - .span_note_mv(spans, format!("{descr} used multiple times")) + .with_span_note(spans, format!("{descr} used multiple times")) .emit()); } } diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index d0e13fa3c0f30..0b2e63b403bf5 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -695,8 +695,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option IntoDiagnostic<'a, G> for AsmClobberNoReg { level, crate::fluent_generated::builtin_macros_asm_clobber_no_reg, ) - .span_mv(self.spans.clone()) - .span_labels_mv(self.clobbers, &lbl1) - .span_labels_mv(self.spans, &lbl2) + .with_span(self.spans.clone()) + .with_span_labels(self.clobbers, &lbl1) + .with_span_labels(self.spans, &lbl2) } } diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 9fb6da6e0121f..477e5c8bec531 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -194,7 +194,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { self.dcx .struct_span_err(attr.span, msg) - .span_label_mv(prev_attr.span, "previous attribute here") + .with_span_label(prev_attr.span, "previous attribute here") .emit(); return; diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index caebb12919fc1..e7d7b4a701227 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -155,7 +155,7 @@ pub fn expand_include<'cx>( if self.p.token != token::Eof { let token = pprust::token_to_string(&self.p.token); let msg = format!("expected item, found `{token}`"); - self.p.dcx().struct_span_err(self.p.token.span, msg).emit(); + self.p.dcx().span_err(self.p.token.span, msg); } break; diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 717f5d9c38a25..4d44e340ae149 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -394,7 +394,7 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) let level = match item.map(|i| &i.kind) { // These were a warning before #92959 and need to continue being that to avoid breaking // stable user code (#94508). - Some(ast::ItemKind::MacCall(_)) => Level::Warning(None), + Some(ast::ItemKind::MacCall(_)) => Level::Warning, _ => Level::Error, }; let mut err = DiagnosticBuilder::<()>::new(dcx, level, msg); @@ -409,8 +409,8 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) ), ); } - err.span_label_mv(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions") - .span_suggestion_mv(attr_sp, + err.with_span_label(attr_sp, "the `#[test]` macro causes a function to be run as a test and has no effect on non-functions") + .with_span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", "#[cfg(test)]", Applicability::MaybeIncorrect) @@ -480,7 +480,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { "argument must be of the form: \ `expected = \"error message\"`", ) - .note_mv( + .with_note( "errors in this attribute were erroneously \ allowed and will become a hard error in a \ future release", diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index df917d527ced8..4babe5bfb813f 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -52,7 +52,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec c, Some(_) => { if diagnostics { - sess.dcx().emit_warning(UnknownCTargetFeaturePrefix { feature: s }); + sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature: s }); } return None; } @@ -79,7 +79,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec { if !unsafe { LLVMRustLLVMHasZlibCompressionForDebugSymbols() } { - sess.dcx().emit_warning(UnknownCompression { algorithm: "zlib" }); + sess.dcx().emit_warn(UnknownCompression { algorithm: "zlib" }); } } rustc_session::config::DebugInfoCompression::Zstd => { if !unsafe { LLVMRustLLVMHasZstdCompressionForDebugSymbols() } { - sess.dcx().emit_warning(UnknownCompression { algorithm: "zstd" }); + sess.dcx().emit_warn(UnknownCompression { algorithm: "zstd" }); } } rustc_session::config::DebugInfoCompression::None => {} @@ -417,7 +417,7 @@ fn report_inline_asm( } let level = match level { llvm::DiagnosticLevel::Error => Level::Error, - llvm::DiagnosticLevel::Warning => Level::Warning(None), + llvm::DiagnosticLevel::Warning => Level::Warning, llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note, }; cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source); @@ -457,7 +457,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) }) .expect("non-UTF8 diagnostic"); - dcx.emit_warning(FromLlvmDiag { message }); + dcx.emit_warn(FromLlvmDiag { message }); } llvm::diagnostic::Unsupported(diagnostic_ref) => { let message = llvm::build_string(|s| { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index 7ad2d03a5edd5..017843c7e7d15 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId}; +use rustc_middle::mir::coverage::{CodeRegion, CounterId, CovTerm, ExpressionId, MappingKind}; /// Must match the layout of `LLVMRustCounterKind`. #[derive(Copy, Clone, Debug)] @@ -149,6 +149,24 @@ pub struct CounterMappingRegion { } impl CounterMappingRegion { + pub(crate) fn from_mapping( + mapping_kind: &MappingKind, + local_file_id: u32, + code_region: &CodeRegion, + ) -> Self { + let &CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region; + match *mapping_kind { + MappingKind::Code(term) => Self::code_region( + Counter::from_term(term), + local_file_id, + start_line, + start_col, + end_line, + end_col, + ), + } + } + pub(crate) fn code_region( counter: Counter, file_id: u32, diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs index cd67fafb8e4e2..d85d9411f03b6 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs @@ -4,7 +4,8 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; use rustc_index::bit_set::BitSet; use rustc_middle::mir::coverage::{ - CodeRegion, CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, Op, + CodeRegion, CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, + MappingKind, Op, }; use rustc_middle::ty::Instance; use rustc_span::Symbol; @@ -64,8 +65,8 @@ impl<'tcx> FunctionCoverageCollector<'tcx> { // For each expression ID that is directly used by one or more mappings, // mark it as not-yet-seen. This indicates that we expect to see a // corresponding `ExpressionUsed` statement during MIR traversal. - for Mapping { term, .. } in &function_coverage_info.mappings { - if let &CovTerm::Expression(id) = term { + for term in function_coverage_info.mappings.iter().flat_map(|m| m.kind.terms()) { + if let CovTerm::Expression(id) = term { expressions_seen.remove(id); } } @@ -221,20 +222,21 @@ impl<'tcx> FunctionCoverage<'tcx> { /// that will be used by `mapgen` when preparing for FFI. pub(crate) fn counter_regions( &self, - ) -> impl Iterator + ExactSizeIterator { + ) -> impl Iterator + ExactSizeIterator { self.function_coverage_info.mappings.iter().map(move |mapping| { - let &Mapping { term, ref code_region } = mapping; - let counter = self.counter_for_term(term); - (counter, code_region) + let Mapping { kind, code_region } = mapping; + let kind = + kind.map_terms(|term| if self.is_zero_term(term) { CovTerm::Zero } else { term }); + (kind, code_region) }) } fn counter_for_term(&self, term: CovTerm) -> Counter { - if is_zero_term(&self.counters_seen, &self.zero_expressions, term) { - Counter::ZERO - } else { - Counter::from_term(term) - } + if self.is_zero_term(term) { Counter::ZERO } else { Counter::from_term(term) } + } + + fn is_zero_term(&self, term: CovTerm) -> bool { + is_zero_term(&self.counters_seen, &self.zero_expressions, term) } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 51df14df644e0..6116a6fd222b3 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -12,7 +12,6 @@ use rustc_hir::def_id::DefId; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::mir; -use rustc_middle::mir::coverage::CodeRegion; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::DefIdSet; use rustc_span::Symbol; @@ -237,7 +236,7 @@ fn encode_mappings_for_function( // Prepare file IDs for each filename, and prepare the mapping data so that // we can pass it through FFI to LLVM. for (file_name, counter_regions_for_file) in - &counter_regions.group_by(|(_counter, region)| region.file_name) + &counter_regions.group_by(|(_, region)| region.file_name) { // Look up the global file ID for this filename. let global_file_id = global_file_table.global_file_id_for_file_name(file_name); @@ -248,17 +247,12 @@ fn encode_mappings_for_function( // For each counter/region pair in this function+file, convert it to a // form suitable for FFI. - for (counter, region) in counter_regions_for_file { - let CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = *region; - - debug!("Adding counter {counter:?} to map for {region:?}"); - mapping_regions.push(CounterMappingRegion::code_region( - counter, + for (mapping_kind, region) in counter_regions_for_file { + debug!("Adding counter {mapping_kind:?} to map for {region:?}"); + mapping_regions.push(CounterMappingRegion::from_mapping( + &mapping_kind, local_file_id.as_u32(), - start_line, - start_col, - end_line, - end_col, + region, )); } } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 6e2c0dc21ad8a..697ce6022984b 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -106,7 +106,7 @@ impl IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_ let message = dcx.eagerly_translate_to_string(message.clone(), diag.args()); DiagnosticBuilder::new(dcx, level, fluent::codegen_llvm_parse_target_machine_config) - .arg_mv("error", message) + .with_arg("error", message) } } @@ -204,8 +204,8 @@ impl IntoDiagnostic<'_, G> for WithLlvmError<'_> { }; self.0 .into_diagnostic(dcx, level) - .primary_message_mv(msg_with_llvm_err) - .arg_mv("llvm_err", self.1) + .with_primary_message(msg_with_llvm_err) + .with_arg("llvm_err", self.1) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 03b79a143cc31..99f4488ac0f97 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -529,7 +529,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec c, Some(_) => { if diagnostics { - sess.dcx().emit_warning(UnknownCTargetFeaturePrefix { feature: s }); + sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature: s }); } return None; } @@ -557,12 +557,12 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.dcx().emit_warning(errors::ProcessingDymutilFailed { + sess.dcx().emit_warn(errors::ProcessingDymutilFailed { status: prog.status, output: escape_string(&output), }); @@ -1091,7 +1091,7 @@ fn strip_symbols_with_external_utility<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.dcx().emit_warning(errors::StrippingDebugInfoFailed { + sess.dcx().emit_warn(errors::StrippingDebugInfoFailed { util, status: prog.status, output: escape_string(&output), @@ -2406,7 +2406,7 @@ fn collect_natvis_visualizers( visualizer_paths.push(visualizer_out_file); } Err(error) => { - sess.dcx().emit_warning(errors::UnableToWriteDebuggerVisualizer { + sess.dcx().emit_warn(errors::UnableToWriteDebuggerVisualizer { path: visualizer_out_file, error, }); diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 695aeb0b2fb77..90f5027c26494 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -446,11 +446,11 @@ impl<'a> Linker for GccLinker<'a> { // FIXME(81490): ld64 doesn't support these flags but macOS 11 // has -needed-l{} / -needed_library {} // but we have no way to detect that here. - self.sess.dcx().emit_warning(errors::Ld64UnimplementedModifier); + self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); } else if self.is_gnu && !self.sess.target.is_like_windows { self.linker_arg("--no-as-needed"); } else { - self.sess.dcx().emit_warning(errors::LinkerUnsupportedModifier); + self.sess.dcx().emit_warn(errors::LinkerUnsupportedModifier); } } self.hint_dynamic(); @@ -504,7 +504,7 @@ impl<'a> Linker for GccLinker<'a> { // FIXME(81490): ld64 as of macOS 11 supports the -needed_framework // flag but we have no way to detect that here. // self.cmd.arg("-needed_framework").arg(framework); - self.sess.dcx().emit_warning(errors::Ld64UnimplementedModifier); + self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); } self.cmd.arg("-framework").arg(framework); } @@ -950,7 +950,7 @@ impl<'a> Linker for MsvcLinker<'a> { } } Err(error) => { - self.sess.dcx().emit_warning(errors::NoNatvisDirectory { error }); + self.sess.dcx().emit_warn(errors::NoNatvisDirectory { error }); } } } @@ -1501,7 +1501,7 @@ impl<'a> Linker for L4Bender<'a> { fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) { // ToDo, not implemented, copy from GCC - self.sess.dcx().emit_warning(errors::L4BenderExportingSymbolsUnimplemented); + self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented); return; } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index d2c6b6e0c7bf6..8e835039970b0 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -573,11 +573,11 @@ fn produce_final_output_artifacts( if crate_output.outputs.contains_key(&output_type) { // 2) Multiple codegen units, with `--emit foo=some_name`. We have // no good solution for this case, so warn the user. - sess.dcx().emit_warning(errors::IgnoringEmitPath { extension }); + sess.dcx().emit_warn(errors::IgnoringEmitPath { extension }); } else if crate_output.single_output_file.is_some() { // 3) Multiple codegen units, with `-o some_name`. We have // no good solution for this case, so warn the user. - sess.dcx().emit_warning(errors::IgnoringOutput { extension }); + sess.dcx().emit_warn(errors::IgnoringOutput { extension }); } else { // 4) Multiple codegen units, but no explicit name. We // just leave the `foo.0.x` files in place. @@ -1847,14 +1847,9 @@ impl SharedEmitterMain { dcx.emit_diagnostic(d); } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { - let err_level = match level { - Level::Error => Level::Error, - Level::Warning(_) => Level::Warning(None), - Level::Note => Level::Note, - _ => bug!("Invalid inline asm diagnostic level"), - }; + assert!(matches!(level, Level::Error | Level::Warning | Level::Note)); let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string(); - let mut err = DiagnosticBuilder::<()>::new(sess.dcx(), err_level, msg); + let mut err = DiagnosticBuilder::<()>::new(sess.dcx(), level, msg); // If the cookie is 0 then we don't have span information. if cookie != 0 { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index f53067d194ac3..36d7234a6ea91 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,6 +1,6 @@ use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; @@ -216,7 +216,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if let Some(fn_sig) = fn_sig() && !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. }) { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0776, @@ -225,7 +225,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { .emit(); } if !tcx.sess.target.llvm_target.contains("thumbv8m") { - struct_span_err!(tcx.dcx(), attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") + struct_span_code_err!(tcx.dcx(), attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") .emit(); } codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY @@ -238,7 +238,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let Some(fn_sig) = fn_sig() && fn_sig.skip_binder().abi() != abi::Abi::Rust { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0737, @@ -265,7 +265,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if s.as_str().contains('\0') { // `#[export_name = ...]` will be converted to a null-terminated string, // so it may not contain any null characters. - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0648, @@ -309,7 +309,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { attr.span, "`#[target_feature(..)]` can only be applied to `unsafe` functions", ) - .span_label_mv(tcx.def_span(did), "not an `unsafe` function") + .with_span_label(tcx.def_span(did), "not an `unsafe` function") .emit(); } else { check_target_feature_trait_unsafe(tcx, did, attr.span); @@ -385,7 +385,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { match segments.as_slice() { [sym::arm, sym::a32] | [sym::arm, sym::t32] => { if !tcx.sess.target.has_thumb_interworking { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0779, @@ -402,7 +402,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } } _ => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0779, @@ -414,7 +414,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } } [] => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0778, @@ -424,7 +424,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { None } _ => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0779, @@ -442,7 +442,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { { rustc_attr::parse_alignment(&literal.kind) .map_err(|msg| { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0589, @@ -469,15 +469,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { Some(MetaItemKind::List(ref items)) => { inline_span = Some(attr.span); if items.len() != 1 { - struct_span_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); + struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument") + .emit(); InlineAttr::None } else if list_contains_name(items, sym::always) { InlineAttr::Always } else if list_contains_name(items, sym::never) { InlineAttr::Never } else { - struct_span_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") - .help_mv("valid inline arguments are `always` and `never`") + struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") + .with_help("valid inline arguments are `always` and `never`") .emit(); InlineAttr::None @@ -492,7 +493,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if !attr.has_name(sym::optimize) { return ia; } - let err = |sp, s| struct_span_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); + let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); match attr.meta_kind() { Some(MetaItemKind::Word) => { err(attr.span, "expected one argument"); @@ -662,7 +663,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option { let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal); tcx.dcx() .struct_span_err(attr.span, msg) - .note_mv("the value may not exceed `u16::MAX`") + .with_note("the value may not exceed `u16::MAX`") .emit(); None } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 7e3b69fa52f49..f90e1906caf0a 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -230,25 +230,25 @@ impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { thorin::Error::DecompressData(_) => build(fluent::codegen_ssa_thorin_decompress_data), thorin::Error::NamelessSection(_, offset) => { build(fluent::codegen_ssa_thorin_section_without_name) - .arg_mv("offset", format!("0x{offset:08x}")) + .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::RelocationWithInvalidSymbol(section, offset) => { build(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol) - .arg_mv("section", section) - .arg_mv("offset", format!("0x{offset:08x}")) + .with_arg("section", section) + .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::MultipleRelocations(section, offset) => { build(fluent::codegen_ssa_thorin_multiple_relocations) - .arg_mv("section", section) - .arg_mv("offset", format!("0x{offset:08x}")) + .with_arg("section", section) + .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::UnsupportedRelocation(section, offset) => { build(fluent::codegen_ssa_thorin_unsupported_relocation) - .arg_mv("section", section) - .arg_mv("offset", format!("0x{offset:08x}")) + .with_arg("section", section) + .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::MissingDwoName(id) => build(fluent::codegen_ssa_thorin_missing_dwo_name) - .arg_mv("id", format!("0x{id:08x}")), + .with_arg("id", format!("0x{id:08x}")), thorin::Error::NoCompilationUnits => { build(fluent::codegen_ssa_thorin_no_compilation_units) } @@ -258,7 +258,7 @@ impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { } thorin::Error::MissingRequiredSection(section) => { build(fluent::codegen_ssa_thorin_missing_required_section) - .arg_mv("section", section) + .with_arg("section", section) } thorin::Error::ParseUnitAbbreviations(_) => { build(fluent::codegen_ssa_thorin_parse_unit_abbreviations) @@ -272,31 +272,30 @@ impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { thorin::Error::ParseUnit(_) => build(fluent::codegen_ssa_thorin_parse_unit), thorin::Error::IncompatibleIndexVersion(section, format, actual) => { build(fluent::codegen_ssa_thorin_incompatible_index_version) - .arg_mv("section", section) - .arg_mv("actual", actual) - .arg_mv("format", format) + .with_arg("section", section) + .with_arg("actual", actual) + .with_arg("format", format) } thorin::Error::OffsetAtIndex(_, index) => { - build(fluent::codegen_ssa_thorin_offset_at_index).arg_mv("index", index) + build(fluent::codegen_ssa_thorin_offset_at_index).with_arg("index", index) } thorin::Error::StrAtOffset(_, offset) => { build(fluent::codegen_ssa_thorin_str_at_offset) - .arg_mv("offset", format!("0x{offset:08x}")) + .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::ParseIndex(_, section) => { - build(fluent::codegen_ssa_thorin_parse_index).arg_mv("section", section) + build(fluent::codegen_ssa_thorin_parse_index).with_arg("section", section) } thorin::Error::UnitNotInIndex(unit) => { build(fluent::codegen_ssa_thorin_unit_not_in_index) - .arg_mv("unit", format!("0x{unit:08x}")) + .with_arg("unit", format!("0x{unit:08x}")) } thorin::Error::RowNotInIndex(_, row) => { - build(fluent::codegen_ssa_thorin_row_not_in_index).arg_mv("row", row) + build(fluent::codegen_ssa_thorin_row_not_in_index).with_arg("row", row) } thorin::Error::SectionNotInRow => build(fluent::codegen_ssa_thorin_section_not_in_row), - thorin::Error::EmptyUnit(unit) => { - build(fluent::codegen_ssa_thorin_empty_unit).arg_mv("unit", format!("0x{unit:08x}")) - } + thorin::Error::EmptyUnit(unit) => build(fluent::codegen_ssa_thorin_empty_unit) + .with_arg("unit", format!("0x{unit:08x}")), thorin::Error::MultipleDebugInfoSection => { build(fluent::codegen_ssa_thorin_multiple_debug_info_section) } @@ -305,10 +304,10 @@ impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { } thorin::Error::NotSplitUnit => build(fluent::codegen_ssa_thorin_not_split_unit), thorin::Error::DuplicateUnit(unit) => build(fluent::codegen_ssa_thorin_duplicate_unit) - .arg_mv("unit", format!("0x{unit:08x}")), + .with_arg("unit", format!("0x{unit:08x}")), thorin::Error::MissingReferencedUnit(unit) => { build(fluent::codegen_ssa_thorin_missing_referenced_unit) - .arg_mv("unit", format!("0x{unit:08x}")) + .with_arg("unit", format!("0x{unit:08x}")) } thorin::Error::NoOutputObjectCreated => { build(fluent::codegen_ssa_thorin_not_output_object_created) @@ -317,19 +316,19 @@ impl IntoDiagnostic<'_, G> for ThorinErrorWrapper { build(fluent::codegen_ssa_thorin_mixed_input_encodings) } thorin::Error::Io(e) => { - build(fluent::codegen_ssa_thorin_io).arg_mv("error", format!("{e}")) + build(fluent::codegen_ssa_thorin_io).with_arg("error", format!("{e}")) } thorin::Error::ObjectRead(e) => { - build(fluent::codegen_ssa_thorin_object_read).arg_mv("error", format!("{e}")) + build(fluent::codegen_ssa_thorin_object_read).with_arg("error", format!("{e}")) } thorin::Error::ObjectWrite(e) => { - build(fluent::codegen_ssa_thorin_object_write).arg_mv("error", format!("{e}")) + build(fluent::codegen_ssa_thorin_object_write).with_arg("error", format!("{e}")) } thorin::Error::GimliRead(e) => { - build(fluent::codegen_ssa_thorin_gimli_read).arg_mv("error", format!("{e}")) + build(fluent::codegen_ssa_thorin_gimli_read).with_arg("error", format!("{e}")) } thorin::Error::GimliWrite(e) => { - build(fluent::codegen_ssa_thorin_gimli_write).arg_mv("error", format!("{e}")) + build(fluent::codegen_ssa_thorin_gimli_write).with_arg("error", format!("{e}")) } _ => unimplemented!("Untranslated thorin error"), } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index c0ce8a54af573..0fef6bc110e10 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -27,7 +27,7 @@ pub fn from_target_feature( let code = "enable = \"..\""; tcx.dcx() .struct_span_err(span, msg) - .span_suggestion_mv(span, "must be of the form", code, Applicability::HasPlaceholders) + .with_span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders) .emit(); }; let rust_features = tcx.features(); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 7fb5f10c6ca75..6947ace17c5e6 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -391,10 +391,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, if ecx.tcx.is_ctfe_mir_available(def) { Ok(ecx.tcx.mir_for_ctfe(def)) } else if ecx.tcx.def_kind(def) == DefKind::AssocConst { - let guar = ecx.tcx.dcx().span_delayed_bug( - rustc_span::DUMMY_SP, - "This is likely a const item that is missing from its impl", - ); + let guar = ecx + .tcx + .dcx() + .delayed_bug("This is likely a const item that is missing from its impl"); throw_inval!(AlreadyReported(guar.into())); } else { // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, @@ -630,7 +630,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // current number of evaluated terminators is a power of 2. The latter gives us a cheap // way to implement exponential backoff. let span = ecx.cur_span(); - ecx.tcx.dcx().emit_warning(LongRunningWarn { span, item_span: ecx.tcx.span }); + ecx.tcx.dcx().emit_warn(LongRunningWarn { span, item_span: ecx.tcx.span }); } } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3047f5d47e4d6..2e4baf26176c3 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1429,7 +1429,7 @@ fn report_ice( } Err(err) => { // The path ICE couldn't be written to disk, provide feedback to the user as to why. - dcx.emit_warning(session_diagnostics::IcePathError { + dcx.emit_warn(session_diagnostics::IcePathError { path: path.clone(), error: err.to_string(), env_var: std::env::var_os("RUSTC_ICE") diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 5c0e210f1472b..97f2efa7874d1 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -87,7 +87,7 @@ fn source_string(file: Lrc, line: &Line) -> String { fn annotation_type_for_level(level: Level) -> AnnotationType { match level { Level::Bug | Level::DelayedBug | Level::Fatal | Level::Error => AnnotationType::Error, - Level::Warning(_) => AnnotationType::Warning, + Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning, Level::Note | Level::OnceNote => AnnotationType::Note, Level::Help | Level::OnceHelp => AnnotationType::Help, // FIXME(#59346): Not sure how to map this level diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 701c1c02ab0ef..d8d6922a1bcda 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -152,7 +152,6 @@ pub enum DiagnosticId { name: String, /// Indicates whether this lint should show up in cargo's future breakage report. has_future_breakage: bool, - is_force_warn: bool, }, } @@ -248,7 +247,8 @@ impl Diagnostic { true } - Level::Warning(_) + Level::ForceWarning(_) + | Level::Warning | Level::Note | Level::OnceNote | Level::Help @@ -262,7 +262,7 @@ impl Diagnostic { &mut self, unstable_to_stable: &FxIndexMap, ) { - if let Level::Expect(expectation_id) | Level::Warning(Some(expectation_id)) = + if let Level::Expect(expectation_id) | Level::ForceWarning(Some(expectation_id)) = &mut self.level { if expectation_id.is_stable() { @@ -292,8 +292,11 @@ impl Diagnostic { } pub(crate) fn is_force_warn(&self) -> bool { - match self.code { - Some(DiagnosticId::Lint { is_force_warn, .. }) => is_force_warn, + match self.level { + Level::ForceWarning(_) => { + assert!(self.is_lint); + true + } _ => false, } } @@ -472,7 +475,7 @@ impl Diagnostic { /// Add a warning attached to this diagnostic. #[rustc_lint_diagnostics] pub fn warn(&mut self, msg: impl Into) -> &mut Self { - self.sub(Level::Warning(None), msg, MultiSpan::new()); + self.sub(Level::Warning, msg, MultiSpan::new()); self } @@ -484,7 +487,7 @@ impl Diagnostic { sp: S, msg: impl Into, ) -> &mut Self { - self.sub(Level::Warning(None), msg, sp.into()); + self.sub(Level::Warning, msg, sp.into()); self } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 3789cdaf354aa..a02909f29c45d 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -30,7 +30,7 @@ where G: EmissionGuarantee, { fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> { - self.node.into_diagnostic(dcx, level).span_mv(self.span) + self.node.into_diagnostic(dcx, level).with_span(self.span) } } @@ -173,26 +173,26 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError { /// `Diagnostic` method. It is mostly to modify existing diagnostics, either /// in a standalone fashion, e.g. `err.code(code)`, or in a chained fashion /// to make multiple modifications, e.g. `err.code(code).span(span)`. -/// - A `self -> Self` method, with `_mv` suffix added (short for "move"). +/// - A `self -> Self` method, which has a `with_` prefix added. /// It is mostly used in a chained fashion when producing a new diagnostic, -/// e.g. `let err = struct_err(msg).code_mv(code)`, or when emitting a new -/// diagnostic , e.g. `struct_err(msg).code_mv(code).emit()`. +/// e.g. `let err = struct_err(msg).with_code(code)`, or when emitting a new +/// diagnostic , e.g. `struct_err(msg).with_code(code).emit()`. /// /// Although the latter method can be used to modify an existing diagnostic, -/// e.g. `err = err.code_mv(code)`, this should be avoided because the former -/// method give shorter code, e.g. `err.code(code)`. +/// e.g. `err = err.with_code(code)`, this should be avoided because the former +/// method gives shorter code, e.g. `err.code(code)`. macro_rules! forward { ( - ($n:ident, $n_mv:ident)($($name:ident: $ty:ty),* $(,)?) + ($f:ident, $with_f:ident)($($name:ident: $ty:ty),* $(,)?) ) => { - #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] - pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { - self.diag.as_mut().unwrap().$n($($name),*); + #[doc = concat!("See [`Diagnostic::", stringify!($f), "()`].")] + pub fn $f(&mut self, $($name: $ty),*) -> &mut Self { + self.diag.as_mut().unwrap().$f($($name),*); self } - #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] - pub fn $n_mv(mut self, $($name: $ty),*) -> Self { - self.diag.as_mut().unwrap().$n($($name),*); + #[doc = concat!("See [`Diagnostic::", stringify!($f), "()`].")] + pub fn $with_f(mut self, $($name: $ty),*) -> Self { + self.diag.as_mut().unwrap().$f($($name),*); self } }; @@ -265,7 +265,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { /// Converts the builder to a `Diagnostic` for later emission, /// unless dcx has disabled such buffering. - pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> { + fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> { if self.dcx.inner.lock().flags.treat_err_as_bug.is_some() { self.emit(); return None; @@ -302,21 +302,21 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { self.emit() } - forward!((span_label, span_label_mv)( + forward!((span_label, with_span_label)( span: Span, label: impl Into, )); - forward!((span_labels, span_labels_mv)( + forward!((span_labels, with_span_labels)( spans: impl IntoIterator, label: &str, )); - forward!((note_expected_found, note_expected_found_mv)( + forward!((note_expected_found, with_note_expected_found)( expected_label: &dyn fmt::Display, expected: DiagnosticStyledString, found_label: &dyn fmt::Display, found: DiagnosticStyledString, )); - forward!((note_expected_found_extra, note_expected_found_extra_mv)( + forward!((note_expected_found_extra, with_note_expected_found_extra)( expected_label: &dyn fmt::Display, expected: DiagnosticStyledString, found_label: &dyn fmt::Display, @@ -324,106 +324,110 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { expected_extra: &dyn fmt::Display, found_extra: &dyn fmt::Display, )); - forward!((note, note_mv)( + forward!((note, with_note)( msg: impl Into, )); - forward!((note_once, note_once_mv)( + forward!((note_once, with_note_once)( msg: impl Into, )); - forward!((span_note, span_note_mv)( + forward!((span_note, with_span_note)( sp: impl Into, msg: impl Into, )); - forward!((span_note_once, span_note_once_mv)( + forward!((span_note_once, with_span_note_once)( sp: impl Into, msg: impl Into, )); - forward!((warn, warn_mv)( + forward!((warn, with_warn)( msg: impl Into, )); - forward!((span_warn, span_warn_mv)( + forward!((span_warn, with_span_warn)( sp: impl Into, msg: impl Into, )); - forward!((help, help_mv)( + forward!((help, with_help)( msg: impl Into, )); - forward!((help_once, help_once_mv)( + forward!((help_once, with_help_once)( msg: impl Into, )); - forward!((span_help, span_help_once_mv)( + forward!((span_help, with_span_help_once)( sp: impl Into, msg: impl Into, )); - forward!((multipart_suggestion, multipart_suggestion_mv)( + forward!((multipart_suggestion, with_multipart_suggestion)( msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, )); - forward!((multipart_suggestion_verbose, multipart_suggestion_verbose_mv)( + forward!((multipart_suggestion_verbose, with_multipart_suggestion_verbose)( msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, )); - forward!((tool_only_multipart_suggestion, tool_only_multipart_suggestion_mv)( + forward!((tool_only_multipart_suggestion, with_tool_only_multipart_suggestion)( msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, )); - forward!((span_suggestion, span_suggestion_mv)( + forward!((span_suggestion, with_span_suggestion)( sp: Span, msg: impl Into, suggestion: impl ToString, applicability: Applicability, )); - forward!((span_suggestions, span_suggestions_mv)( + forward!((span_suggestions, with_span_suggestions)( sp: Span, msg: impl Into, suggestions: impl IntoIterator, applicability: Applicability, )); - forward!((multipart_suggestions, multipart_suggestions_mv)( + forward!((multipart_suggestions, with_multipart_suggestions)( msg: impl Into, suggestions: impl IntoIterator>, applicability: Applicability, )); - forward!((span_suggestion_short, span_suggestion_short_mv)( + forward!((span_suggestion_short, with_span_suggestion_short)( sp: Span, msg: impl Into, suggestion: impl ToString, applicability: Applicability, )); - forward!((span_suggestion_verbose, span_suggestion_verbose_mv)( + forward!((span_suggestion_verbose, with_span_suggestion_verbose)( sp: Span, msg: impl Into, suggestion: impl ToString, applicability: Applicability, )); - forward!((span_suggestion_hidden, span_suggestion_hidden_mv)( + forward!((span_suggestion_hidden, with_span_suggestion_hidden)( sp: Span, msg: impl Into, suggestion: impl ToString, applicability: Applicability, )); - forward!((tool_only_span_suggestion, tool_only_span_suggestion_mv)( + forward!((tool_only_span_suggestion, with_tool_only_span_suggestion)( sp: Span, msg: impl Into, suggestion: impl ToString, applicability: Applicability, )); - forward!((primary_message, primary_message_mv)( + forward!((primary_message, with_primary_message)( msg: impl Into, )); - forward!((span, span_mv)( + forward!((span, with_span)( sp: impl Into, )); - forward!((code, code_mv)( + forward!((code, with_code)( s: DiagnosticId, )); - forward!((arg, arg_mv)( + forward!((arg, with_arg)( name: impl Into>, arg: impl IntoDiagnosticArg, )); - forward!((subdiagnostic, subdiagnostic_mv)( + forward!((subdiagnostic, with_subdiagnostic)( + subdiagnostic: impl crate::AddToDiagnostic, + )); + forward!((eager_subdiagnostic, with_eager_subdiagnostic)( + dcx: &DiagCtxt, subdiagnostic: impl crate::AddToDiagnostic, )); } @@ -453,13 +457,13 @@ impl Drop for DiagnosticBuilder<'_, G> { } #[macro_export] -macro_rules! struct_span_err { +macro_rules! struct_span_code_err { ($dcx:expr, $span:expr, $code:ident, $($message:tt)*) => ({ $dcx.struct_span_err( $span, format!($($message)*), ) - .code_mv($crate::error_code!($code)) + .with_code($crate::error_code!($code)) }) } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 58d4d2caf2ee1..39252dea28303 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -252,40 +252,40 @@ impl IntoDiagnostic<'_, G> for TargetDataLayoutErrors<'_> match self { TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_address_space) - .arg_mv("addr_space", addr_space) - .arg_mv("cause", cause) - .arg_mv("err", err) + .with_arg("addr_space", addr_space) + .with_arg("cause", cause) + .with_arg("err", err) } TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits) - .arg_mv("kind", kind) - .arg_mv("bit", bit) - .arg_mv("cause", cause) - .arg_mv("err", err) + .with_arg("kind", kind) + .with_arg("bit", bit) + .with_arg("cause", cause) + .with_arg("err", err) } TargetDataLayoutErrors::MissingAlignment { cause } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_missing_alignment) - .arg_mv("cause", cause) + .with_arg("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_alignment) - .arg_mv("cause", cause) - .arg_mv("err_kind", err.diag_ident()) - .arg_mv("align", err.align()) + .with_arg("cause", cause) + .with_arg("err_kind", err.diag_ident()) + .with_arg("align", err.align()) } TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_inconsistent_architecture) - .arg_mv("dl", dl) - .arg_mv("target", target) + .with_arg("dl", dl) + .with_arg("target", target) } TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_inconsistent_pointer_width) - .arg_mv("pointer_size", pointer_size) - .arg_mv("target", target) + .with_arg("pointer_size", pointer_size) + .with_arg("target", target) } TargetDataLayoutErrors::InvalidBitsSize { err } => { DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits_size) - .arg_mv("err", err) + .with_arg("err", err) } } } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 52fcb50e9fb96..87bf9c234564b 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -198,7 +198,7 @@ impl Emitter for JsonEmitter { .into_iter() .map(|mut diag| { if diag.level == crate::Level::Allow { - diag.level = crate::Level::Warning(None); + diag.level = crate::Level::Warning; } FutureBreakageItem { diagnostic: EmitTyped::Diagnostic(Diagnostic::from_errors_diagnostic( diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 76b7e0d79a98c..8fb539fc3582f 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -420,6 +420,7 @@ pub struct DiagCtxt { /// as well as inconsistent state observation. struct DiagCtxtInner { flags: DiagCtxtFlags, + /// The number of lint errors that have been emitted. lint_err_count: usize, /// The number of errors that have been emitted, including duplicates. @@ -427,8 +428,13 @@ struct DiagCtxtInner { /// This is not necessarily the count that's reported to the user once /// compilation ends. err_count: usize, - warn_count: usize, deduplicated_err_count: usize, + /// The warning count, used for a recap upon finishing + deduplicated_warn_count: usize, + /// Has this diagnostic context printed any diagnostics? (I.e. has + /// `self.emitter.emit_diagnostic()` been called? + has_printed: bool, + emitter: Box, span_delayed_bugs: Vec, good_path_delayed_bugs: Vec, @@ -455,9 +461,6 @@ struct DiagCtxtInner { /// When `.abort_if_errors()` is called, these are also emitted. stashed_diagnostics: FxIndexMap<(Span, StashKey), Diagnostic>, - /// The warning count, used for a recap upon finishing - deduplicated_warn_count: usize, - future_breakage_diagnostics: Vec, /// The [`Self::unstable_expect_diagnostics`] should be empty when this struct is @@ -513,7 +516,7 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) { (*f)(diag) } -pub static TRACK_DIAGNOSTICS: AtomicRef = +pub static TRACK_DIAGNOSTIC: AtomicRef = AtomicRef::new(&(default_track_diagnostic as _)); #[derive(Copy, Clone, Default)] @@ -547,8 +550,7 @@ impl Drop for DiagCtxtInner { // instead of "require some error happened". Sadly that isn't ideal, as // lints can be `#[allow]`'d, potentially leading to this triggering. // Also, "good path" should be replaced with a better naming. - let has_any_message = self.err_count > 0 || self.lint_err_count > 0 || self.warn_count > 0; - if !has_any_message && !self.suppressed_expected_diag && !std::thread::panicking() { + if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() { let bugs = std::mem::replace(&mut self.good_path_delayed_bugs, Vec::new()); self.flush_delayed( bugs, @@ -594,9 +596,9 @@ impl DiagCtxt { flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() }, lint_err_count: 0, err_count: 0, - warn_count: 0, deduplicated_err_count: 0, deduplicated_warn_count: 0, + has_printed: false, emitter, span_delayed_bugs: Vec::new(), good_path_delayed_bugs: Vec::new(), @@ -647,10 +649,11 @@ impl DiagCtxt { /// the overall count of emitted error diagnostics. pub fn reset_err_count(&self) { let mut inner = self.inner.borrow_mut(); + inner.lint_err_count = 0; inner.err_count = 0; - inner.warn_count = 0; inner.deduplicated_err_count = 0; inner.deduplicated_warn_count = 0; + inner.has_printed = false; // actually free the underlying memory (which `clear` would not do) inner.span_delayed_bugs = Default::default(); @@ -669,16 +672,11 @@ impl DiagCtxt { let key = (span.with_parent(None), key); if diag.is_error() { - if diag.level == Error && diag.is_lint { + if diag.is_lint { inner.lint_err_count += 1; } else { inner.err_count += 1; } - } else { - // Warnings are only automatically flushed if they're forced. - if diag.is_force_warn() { - inner.warn_count += 1; - } } // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic @@ -693,15 +691,11 @@ impl DiagCtxt { let key = (span.with_parent(None), key); let diag = inner.stashed_diagnostics.remove(&key)?; if diag.is_error() { - if diag.level == Error && diag.is_lint { + if diag.is_lint { inner.lint_err_count -= 1; } else { inner.err_count -= 1; } - } else { - if diag.is_force_warn() { - inner.warn_count -= 1; - } } Some(DiagnosticBuilder::new_diagnostic(self, diag)) } @@ -727,7 +721,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, ()> { - self.struct_warn(msg).span_mv(span) + self.struct_warn(msg).with_span(span) } /// Construct a builder at the `Warning` level with the `msg`. @@ -738,7 +732,7 @@ impl DiagCtxt { #[rustc_lint_diagnostics] #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Warning(None), msg) + DiagnosticBuilder::new(self, Warning, msg) } /// Construct a builder at the `Allow` level with the `msg`. @@ -767,7 +761,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_> { - self.struct_err(msg).span_mv(span) + self.struct_err(msg).with_span(span) } /// Construct a builder at the `Error` level with the `msg`. @@ -786,7 +780,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, FatalAbort> { - self.struct_fatal(msg).span_mv(span) + self.struct_fatal(msg).with_span(span) } /// Construct a builder at the `Fatal` level with the `msg`. @@ -827,7 +821,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, BugAbort> { - self.struct_bug(msg).span_mv(span) + self.struct_bug(msg).with_span(span) } #[rustc_lint_diagnostics] @@ -865,10 +859,16 @@ impl DiagCtxt { /// For example, it can be used to create an [`ErrorGuaranteed`] /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission /// directly). - /// - /// If no span is available, use [`DUMMY_SP`]. - /// - /// [`DUMMY_SP`]: rustc_span::DUMMY_SP + #[track_caller] + pub fn delayed_bug(&self, msg: impl Into) -> ErrorGuaranteed { + let treat_next_err_as_bug = self.inner.borrow().treat_next_err_as_bug(); + if treat_next_err_as_bug { + self.bug(msg); + } + DiagnosticBuilder::::new(self, DelayedBug, msg).emit() + } + + /// Like `delayed_bug`, but takes an additional span. /// /// Note: this function used to be called `delay_span_bug`. It was renamed /// to match similar functions like `span_err`, `span_warn`, etc. @@ -882,9 +882,7 @@ impl DiagCtxt { if treat_next_err_as_bug { self.span_bug(sp, msg); } - let mut diagnostic = Diagnostic::new(DelayedBug, msg); - diagnostic.span(sp); - self.emit_diagnostic(diagnostic).unwrap() + DiagnosticBuilder::::new(self, DelayedBug, msg).with_span(sp).emit() } // FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's @@ -909,7 +907,7 @@ impl DiagCtxt { span: impl Into, msg: impl Into, ) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Note, msg).span_mv(span) + DiagnosticBuilder::new(self, Note, msg).with_span(span) } #[rustc_lint_diagnostics] @@ -1001,7 +999,7 @@ impl DiagCtxt { (0, 0) => return, (0, _) => inner .emitter - .emit_diagnostic(&Diagnostic::new(Warning(None), DiagnosticMessage::Str(warnings))), + .emit_diagnostic(&Diagnostic::new(Warning, DiagnosticMessage::Str(warnings))), (_, 0) => { inner.emit_diagnostic(Diagnostic::new(Fatal, errors)); } @@ -1086,16 +1084,16 @@ impl DiagCtxt { } #[track_caller] - pub fn create_warning<'a>( + pub fn create_warn<'a>( &'a self, warning: impl IntoDiagnostic<'a, ()>, ) -> DiagnosticBuilder<'a, ()> { - warning.into_diagnostic(self, Warning(None)) + warning.into_diagnostic(self, Warning) } #[track_caller] - pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { - self.create_warning(warning).emit() + pub fn emit_warn<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { + self.create_warn(warning).emit() } #[track_caller] @@ -1227,7 +1225,7 @@ impl DiagCtxt { // Note: we prefer implementing operations on `DiagCtxt`, rather than // `DiagCtxtInner`, whenever possible. This minimizes functions where // `DiagCtxt::foo()` just borrows `inner` and forwards a call to -// `HanderInner::foo`. +// `DiagCtxtInner::foo`. impl DiagCtxtInner { /// Emit all stashed diagnostics. fn emit_stashed_diagnostics(&mut self) -> Option { @@ -1237,21 +1235,17 @@ impl DiagCtxtInner { for diag in diags { // Decrement the count tracking the stash; emitting will increment it. if diag.is_error() { - if diag.level == Error && diag.is_lint { + if diag.is_lint { self.lint_err_count -= 1; } else { self.err_count -= 1; } } else { - if diag.is_force_warn() { - self.warn_count -= 1; - } else { - // Unless they're forced, don't flush stashed warnings when - // there are errors, to avoid causing warning overload. The - // stash would've been stolen already if it were important. - if has_errors { - continue; - } + // Unless they're forced, don't flush stashed warnings when + // there are errors, to avoid causing warning overload. The + // stash would've been stolen already if it were important. + if !diag.is_force_warn() && has_errors { + continue; } } let reported_this = self.emit_diagnostic(diag); @@ -1300,23 +1294,20 @@ impl DiagCtxtInner { self.fulfilled_expectations.insert(expectation_id.normalize()); } - if matches!(diagnostic.level, Warning(_)) - && !self.flags.can_emit_warnings - && !diagnostic.is_force_warn() - { + if diagnostic.level == Warning && !self.flags.can_emit_warnings { if diagnostic.has_future_breakage() { - (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); + (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); } return None; } if matches!(diagnostic.level, Expect(_) | Allow) { - (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); + (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {}); return None; } let mut guaranteed = None; - (*TRACK_DIAGNOSTICS)(diagnostic, &mut |mut diagnostic| { + (*TRACK_DIAGNOSTIC)(diagnostic, &mut |mut diagnostic| { if let Some(ref code) = diagnostic.code { self.emitted_diagnostic_codes.insert(code.clone()); } @@ -1355,12 +1346,13 @@ impl DiagCtxtInner { self.emitter.emit_diagnostic(&diagnostic); if diagnostic.is_error() { self.deduplicated_err_count += 1; - } else if let Warning(_) = diagnostic.level { + } else if matches!(diagnostic.level, ForceWarning(_) | Warning) { self.deduplicated_warn_count += 1; } + self.has_printed = true; } if diagnostic.is_error() { - if diagnostic.level == Error && diagnostic.is_lint { + if diagnostic.is_lint { self.bump_lint_err_count(); } else { self.bump_err_count(); @@ -1370,8 +1362,6 @@ impl DiagCtxtInner { { guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } - } else { - self.bump_warn_count(); } }); @@ -1467,10 +1457,6 @@ impl DiagCtxtInner { self.panic_if_treat_err_as_bug(); } - fn bump_warn_count(&mut self) { - self.warn_count += 1; - } - fn panic_if_treat_err_as_bug(&self) { if self.treat_err_as_bug() { match ( @@ -1558,14 +1544,17 @@ pub enum Level { /// Its `EmissionGuarantee` is `ErrorGuaranteed`. Error, - /// A warning about the code being compiled. Does not prevent compilation from finishing. + /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation + /// from finishing. /// - /// This [`LintExpectationId`] is used for expected lint diagnostics, which should - /// also emit a warning due to the `force-warn` flag. In all other cases this should - /// be `None`. + /// The [`LintExpectationId`] is used for expected lint diagnostics. In all other cases this + /// should be `None`. + ForceWarning(Option), + + /// A warning about the code being compiled. Does not prevent compilation from finishing. /// /// Its `EmissionGuarantee` is `()`. - Warning(Option), + Warning, /// A message giving additional context. Rare, because notes are more commonly attached to other /// diagnostics such as errors. @@ -1618,7 +1607,7 @@ impl Level { Bug | DelayedBug | Fatal | Error => { spec.set_fg(Some(Color::Red)).set_intense(true); } - Warning(_) => { + ForceWarning(_) | Warning => { spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); } Note | OnceNote => { @@ -1637,7 +1626,7 @@ impl Level { match self { Bug | DelayedBug => "error: internal compiler error", Fatal | Error => "error", - Warning(_) => "warning", + ForceWarning(_) | Warning => "warning", Note | OnceNote => "note", Help | OnceHelp => "help", FailureNote => "failure-note", @@ -1651,7 +1640,7 @@ impl Level { pub fn get_expectation_id(&self) -> Option { match self { - Expect(id) | Warning(Some(id)) => Some(*id), + Expect(id) | ForceWarning(Some(id)) => Some(*id), _ => None, } } diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 2746e888b8da2..eec86c36aedae 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -180,7 +180,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, } Error(err_sp, msg) => { let span = err_sp.substitute_dummy(self.root_span); - self.cx.dcx().struct_span_err(span, msg.clone()).emit(); + self.cx.dcx().span_err(span, msg.clone()); self.result = Some(DummyResult::any(span)); } ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)), diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index b86831b8222d9..ac5136539c382 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -680,7 +680,7 @@ impl TtParser { // edition-specific matching behavior for non-terminals. let nt = match parser.to_mut().parse_nonterminal(kind) { Err(err) => { - let guarantee = err.span_label_mv( + let guarantee = err.with_span_label( span, format!( "while parsing argument for this `{kind}` macro fragment" diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 68296700987ef..a56c980791aff 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -458,7 +458,7 @@ pub fn compile_declarative_macro( return dummy_syn_ext(); } Error(sp, msg) => { - sess.dcx().struct_span_err(sp.substitute_dummy(def.span), msg).emit(); + sess.dcx().span_err(sp.substitute_dummy(def.span), msg); return dummy_syn_ext(); } ErrorReported(_) => { diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index c3e4f40c166a0..889f43ed2032d 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -86,7 +86,7 @@ pub(super) fn parse( ); sess.dcx .struct_span_err(span, msg) - .help_mv(VALID_FRAGMENT_NAMES_MSG) + .with_help(VALID_FRAGMENT_NAMES_MSG) .emit(); token::NonterminalKind::Ident }, diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 0053f5503186b..6392894fea2aa 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -380,7 +380,7 @@ impl ToInternal for Level { fn to_internal(self) -> rustc_errors::Level { match self { Level::Error => rustc_errors::Level::Error, - Level::Warning => rustc_errors::Level::Warning(None), + Level::Warning => rustc_errors::Level::Warning, Level::Note => rustc_errors::Level::Note, Level::Help => rustc_errors::Level::Help, _ => unreachable!("unknown proc_macro::Level variant: {:?}", self), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 082658a3a3b06..58ac9668da5e9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2405,6 +2405,39 @@ impl<'hir> Ty<'hir> { my_visitor.visit_ty(self); my_visitor.0 } + + /// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to + /// use inference to provide suggestions for the appropriate type if possible. + pub fn is_suggestable_infer_ty(&self) -> bool { + fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool { + generic_args.iter().any(|arg| match arg { + GenericArg::Type(ty) => ty.is_suggestable_infer_ty(), + GenericArg::Infer(_) => true, + _ => false, + }) + } + debug!(?self); + match &self.kind { + TyKind::Infer => true, + TyKind::Slice(ty) => ty.is_suggestable_infer_ty(), + TyKind::Array(ty, length) => { + ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(_, _)) + } + TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty), + TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(), + TyKind::OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args), + TyKind::Path(QPath::TypeRelative(ty, segment)) => { + ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args) + } + TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => { + ty_opt.is_some_and(Self::is_suggestable_infer_ty) + || segments + .iter() + .any(|segment| are_suggestable_generic_args(segment.args().args)) + } + _ => false, + } + } } /// Not represented directly in the AST; referred to by name through a `ty_path`. @@ -2735,7 +2768,7 @@ pub enum FnRetTy<'hir> { Return(&'hir Ty<'hir>), } -impl FnRetTy<'_> { +impl<'hir> FnRetTy<'hir> { #[inline] pub fn span(&self) -> Span { match *self { @@ -2743,6 +2776,15 @@ impl FnRetTy<'_> { Self::Return(ref ty) => ty.span, } } + + pub fn get_infer_ret_ty(&self) -> Option<&'hir Ty<'hir>> { + if let Self::Return(ty) = self { + if ty.is_suggestable_infer_ty() { + return Some(*ty); + } + } + None + } } /// Represents `for<...>` binder before a closure diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index 38184a5dd1824..1f88aaa6a4b01 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashMap; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -305,7 +305,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { binding.span, format!("{} `{}` is private", assoc_item.kind, binding.item_name), ) - .span_label_mv(binding.span, format!("private {}", assoc_item.kind)) + .with_span_label(binding.span, format!("private {}", assoc_item.kind)) .emit(); } tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None); @@ -462,7 +462,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { late_bound_in_trait_ref, late_bound_in_ty, |br_name| { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), binding.span, E0582, diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index 24b55461a4277..fc2ed104b3dc8 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -7,7 +7,7 @@ use crate::fluent_generated as fluent; use crate::traits::error_reporting::report_object_safety_error; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordMap; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::traits::FulfillmentError; @@ -346,7 +346,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { candidates: Vec, span: Span, ) -> ErrorGuaranteed { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.tcx().dcx(), name.span, E0034, @@ -445,7 +445,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { String::new() }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), name.span, E0220, @@ -697,7 +697,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let names = names.join(", "); trait_bound_spans.sort(); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), trait_bound_spans, E0191, diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index adc6a9de8086f..e2cd4d5f21c76 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -5,7 +5,7 @@ use crate::astconv::{ }; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; @@ -27,7 +27,7 @@ fn generic_arg_mismatch_err( help: Option, ) -> ErrorGuaranteed { let sess = tcx.sess; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), arg.span(), E0747, @@ -70,7 +70,7 @@ fn generic_arg_mismatch_err( Res::Err => { add_braces_suggestion(arg, &mut err); return err - .primary_message_mv("unresolved item provided when a constant was expected") + .with_primary_message("unresolved item provided when a constant was expected") .emit(); } Res::Def(DefKind::TyParam, src_def_id) => { @@ -650,8 +650,8 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( if position == GenericArgPosition::Value && args.num_lifetime_params() != param_counts.lifetimes { - struct_span_err!(tcx.dcx(), span, E0794, "{}", msg) - .span_note_mv(span_late, note) + struct_span_code_err!(tcx.dcx(), span, E0794, "{}", msg) + .with_span_note(span_late, note) .emit(); } else { let mut multispan = MultiSpan::from_span(span); diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 6675f517cfa15..3761d52951709 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -213,7 +213,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; let mut diag = - rustc_errors::struct_span_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg); + rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg); if self_ty.span.can_be_used_for_suggestions() && !self.maybe_lint_impl_trait(self_ty, &mut diag) { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index cdfb4c6389e1d..1f47564649eda 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -18,8 +18,8 @@ use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ - error_code, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, - FatalError, MultiSpan, + error_code, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, + ErrorGuaranteed, FatalError, MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -866,7 +866,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { traits: &[String], name: Symbol, ) -> ErrorGuaranteed { - let mut err = struct_span_err!(self.tcx().dcx(), span, E0223, "ambiguous associated type"); + let mut err = + struct_span_code_err!(self.tcx().dcx(), span, E0223, "ambiguous associated type"); if self .tcx() .resolutions(()) @@ -1313,7 +1314,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let msg = format!("expected type, found variant `{assoc_ident}`"); tcx.dcx().span_err(span, msg) } else if qself_ty.is_enum() { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), assoc_ident.span, E0599, @@ -1354,7 +1355,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { reported } else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() { // `::Assoc` makes no sense. - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(alias_ty.def_id), E0667, @@ -1617,9 +1618,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let def_span = tcx.def_span(item); tcx.dcx() .struct_span_err(span, msg) - .code_mv(rustc_errors::error_code!(E0624)) - .span_label_mv(span, format!("private {kind}")) - .span_label_mv(def_span, format!("{kind} defined here")) + .with_code(rustc_errors::error_code!(E0624)) + .with_span_label(span, format!("private {kind}")) + .with_span_label(def_span, format!("{kind} defined here")) .emit(); } tcx.check_stability(item, Some(block), span, None); @@ -1850,7 +1851,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; let last_span = *arg_spans.last().unwrap(); let span: MultiSpan = arg_spans.into(); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.tcx().dcx(), span, E0109, @@ -2601,7 +2602,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output); self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), decl.output.span(), E0581, diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 703e0bdc40edb..ea2f5f50b5c60 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -2,7 +2,7 @@ use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBou use crate::bounds::Bounds; use crate::errors::TraitObjectDeclaredWithNoTraits; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; @@ -89,7 +89,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if regular_traits.len() > 1 { let first_trait = ®ular_traits[0]; let additional_trait = ®ular_traits[1]; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), additional_trait.bottom().1, E0225, @@ -290,7 +290,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if references_self { let def_id = i.bottom().0.def_id(); - struct_span_err!( + struct_span_code_err!( tcx.dcx(), i.bottom().1, E0038, @@ -298,7 +298,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.def_descr(def_id), tcx.item_name(def_id), ) - .note_mv( + .with_note( rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![]) .error_msg(), ) @@ -375,7 +375,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ast_region_to_region(lifetime, None) } else { self.re_infer(None, span).unwrap_or_else(|| { - let err = struct_span_err!( + let err = struct_span_code_err!( tcx.dcx(), span, E0228, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 7f23c04ce2df3..6265ddafef054 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -37,7 +37,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { match tcx.sess.target.is_abi_supported(abi) { Some(true) => (), Some(false) => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), span, E0570, @@ -58,7 +58,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { // This ABI is only allowed on function pointers if abi == Abi::CCmseNonSecureCall { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), span, E0781, @@ -560,14 +560,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { (0, _) => ("const", "consts", None), _ => ("type or const", "types or consts", None), }; - struct_span_err!( + struct_span_code_err!( tcx.dcx(), item.span, E0044, "foreign items may not have {kinds} parameters", ) - .span_label_mv(item.span, format!("can't have {kinds} parameters")) - .help_mv( + .with_span_label(item.span, format!("can't have {kinds} parameters")) + .with_help( // FIXME: once we start storing spans for type arguments, turn this // into a suggestion. format!( @@ -659,10 +659,7 @@ pub(super) fn check_specialization_validity<'tcx>( if !tcx.is_impl_trait_in_trait(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { - tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("parent item: {parent_impl:?} not marked as default"), - ); + tcx.dcx().delayed_bug(format!("parent item: {parent_impl:?} not marked as default")); } } } @@ -687,7 +684,7 @@ fn check_impl_items_against_trait<'tcx>( ty::ImplPolarity::Negative => { if let [first_item_ref, ..] = impl_item_refs { let first_item_span = tcx.def_span(first_item_ref); - struct_span_err!( + struct_span_code_err!( tcx.dcx(), first_item_span, E0749, @@ -804,10 +801,9 @@ fn check_impl_items_against_trait<'tcx>( }; tcx.dcx() .struct_span_err(tcx.def_span(def_id), msg) - .note_mv(format!( - "specialization behaves in inconsistent and \ - surprising ways with {feature}, \ - and for now is disallowed" + .with_note(format!( + "specialization behaves in inconsistent and surprising ways with \ + {feature}, and for now is disallowed" )) .emit(); } @@ -840,13 +836,13 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { { let fields = &def.non_enum_variant().fields; if fields.is_empty() { - struct_span_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit(); + struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit(); return; } let e = fields[FieldIdx::from_u32(0)].ty(tcx, args); if !fields.iter().all(|f| f.ty(tcx, args) == e) { - struct_span_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous") - .span_label_mv(sp, "SIMD elements must have the same type") + struct_span_code_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous") + .with_span_label(sp, "SIMD elements must have the same type") .emit(); return; } @@ -858,10 +854,10 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { }; if let Some(len) = len { if len == 0 { - struct_span_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit(); + struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit(); return; } else if len > MAX_SIMD_LANES { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), sp, E0075, @@ -884,7 +880,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { if matches!(t.kind(), ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)) => { /* struct([f32; 4]) is ok */ } _ => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), sp, E0077, @@ -907,7 +903,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { && let Some(repr_pack) = repr.pack && pack as u64 != repr_pack.bytes() { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), sp, E0634, @@ -918,7 +914,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { } } if repr.align.is_some() { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), sp, E0587, @@ -927,7 +923,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { .emit(); } else { if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut vec![]) { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), sp, E0588, @@ -1117,13 +1113,13 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { if def.variants().is_empty() { if let Some(attr) = tcx.get_attrs(def_id, sym::repr).next() { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), attr.span, E0084, "unsupported representation for zero-variant enum" ) - .span_label_mv(tcx.def_span(def_id), "zero-variant enum") + .with_span_label(tcx.def_span(def_id), "zero-variant enum") .emit(); } } @@ -1156,7 +1152,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var)); if disr_non_unit || (disr_units && has_non_units) { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0732, @@ -1242,7 +1238,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) if discrs[i].1.val == discrs[o].1.val { let err = error.get_or_insert_with(|| { - let mut ret = struct_span_err!( + let mut ret = struct_span_code_err!( tcx.dcx(), tcx.def_span(adt.did()), E0081, @@ -1309,9 +1305,15 @@ pub(super) fn check_type_params_are_used<'tcx>( && let ty::GenericParamDefKind::Type { .. } = param.kind { let span = tcx.def_span(param.def_id); - struct_span_err!(tcx.dcx(), span, E0091, "type parameter `{}` is unused", param.name,) - .span_label_mv(span, "unused type parameter") - .emit(); + struct_span_code_err!( + tcx.dcx(), + span, + E0091, + "type parameter `{}` is unused", + param.name, + ) + .with_span_label(span, "unused type parameter") + .emit(); } } } @@ -1329,7 +1331,7 @@ fn opaque_type_cycle_error( opaque_def_id: LocalDefId, span: Span, ) -> ErrorGuaranteed { - let mut err = struct_span_err!(tcx.dcx(), span, E0720, "cannot resolve opaque type"); + let mut err = struct_span_code_err!(tcx.dcx(), span, E0720, "cannot resolve opaque type"); let mut label = false; if let Some((def_id, visitor)) = get_owner_return_paths(tcx, opaque_def_id) { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 46b5c1a94dec9..469e7a6a13c50 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2,7 +2,7 @@ use super::potentially_plural_count; use crate::errors::LifetimesOrBoundsMismatchOnTrait; use hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed}; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, DiagnosticId, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; @@ -19,7 +19,7 @@ use rustc_middle::ty::{ self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ @@ -625,7 +625,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) { Ok(()) => {} Err(terr) => { - let mut diag = struct_span_err!( + let mut diag = struct_span_code_err!( tcx.dcx(), cause.span(), E0053, @@ -934,17 +934,15 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { return_span, "return type captures more lifetimes than trait definition", ) - .span_label_mv(self.tcx.def_span(def_id), "this lifetime was captured") - .span_note_mv( + .with_span_label(self.tcx.def_span(def_id), "this lifetime was captured") + .with_span_note( self.tcx.def_span(self.def_id), "hidden type must only reference lifetimes captured by this impl trait", ) - .note_mv(format!("hidden type inferred to be `{}`", self.ty)) + .with_note(format!("hidden type inferred to be `{}`", self.ty)) .emit() } - _ => { - self.tcx.dcx().span_delayed_bug(DUMMY_SP, "should've been able to remap region") - } + _ => self.tcx.dcx().delayed_bug("should've been able to remap region"), }; return Err(guar); }; @@ -972,7 +970,7 @@ fn report_trait_method_mismatch<'tcx>( let (impl_err_span, trait_err_span) = extract_spans_for_error_reporting(infcx, terr, &cause, impl_m, trait_m); - let mut diag = struct_span_err!( + let mut diag = struct_span_code_err!( tcx.dcx(), impl_err_span, E0053, @@ -1217,7 +1215,7 @@ fn compare_self_type<'tcx>( (false, true) => { let self_descr = self_string(impl_m); let impl_m_span = tcx.def_span(impl_m.def_id); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), impl_m_span, E0185, @@ -1237,7 +1235,7 @@ fn compare_self_type<'tcx>( (true, false) => { let self_descr = self_string(trait_m); let impl_m_span = tcx.def_span(impl_m.def_id); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), impl_m_span, E0186, @@ -1303,8 +1301,7 @@ fn compare_number_of_generics<'tcx>( // inheriting the generics from will also have mismatched arguments, and // we'll report an error for that instead. Delay a bug for safety, though. if trait_.is_impl_trait_in_trait() { - return Err(tcx.dcx().span_delayed_bug( - rustc_span::DUMMY_SP, + return Err(tcx.dcx().delayed_bug( "errors comparing numbers of generics of trait/impl functions were not emitted", )); } @@ -1463,7 +1460,7 @@ fn compare_number_of_method_arguments<'tcx>( }) .unwrap_or_else(|| tcx.def_span(impl_m.def_id)); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), impl_span, E0050, @@ -1530,7 +1527,7 @@ fn compare_synthetic_generics<'tcx>( let impl_def_id = impl_def_id.expect_local(); let impl_span = tcx.def_span(impl_def_id); let trait_span = tcx.def_span(trait_def_id); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), impl_span, E0643, @@ -1689,7 +1686,7 @@ fn compare_generic_param_kinds<'tcx>( let param_impl_span = tcx.def_span(param_impl.def_id); let param_trait_span = tcx.def_span(param_trait.def_id); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), param_impl_span, E0053, @@ -1836,7 +1833,7 @@ fn compare_const_predicate_entailment<'tcx>( let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const(); cause.span = ty.span; - let mut diag = struct_span_err!( + let mut diag = struct_span_code_err!( tcx.dcx(), cause.span, E0326, diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index fd1571426c86a..f7fc0c81b953b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -7,7 +7,7 @@ use rustc_middle::traits::{ObligationCause, Reveal}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use rustc_trait_selection::traits::{ elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt, }; @@ -153,10 +153,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( trait_m_sig.inputs_and_output, )); if !ocx.select_all_or_error().is_empty() { - tcx.dcx().span_delayed_bug( - DUMMY_SP, - "encountered errors when checking RPITIT refinement (selection)", - ); + tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); return; } let outlives_env = OutlivesEnvironment::with_bounds( @@ -165,18 +162,12 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( ); let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { - tcx.dcx().span_delayed_bug( - DUMMY_SP, - "encountered errors when checking RPITIT refinement (regions)", - ); + tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (regions)"); return; } // Resolve any lifetime variables that may have been introduced during normalization. let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else { - tcx.dcx().span_delayed_bug( - DUMMY_SP, - "encountered errors when checking RPITIT refinement (resolution)", - ); + tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (resolution)"); return; }; diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index ff78d040aca17..3275a81c3ddc7 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -2,7 +2,7 @@ // // We don't do any drop checking during hir typeck. use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, ErrorGuaranteed}; +use rustc_errors::{struct_span_code_err, ErrorGuaranteed}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_middle::ty::util::CheckRegions; @@ -88,8 +88,12 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( let drop_impl_span = tcx.def_span(drop_impl_did); let item_span = tcx.def_span(self_type_did); let self_descr = tcx.def_descr(self_type_did); - let mut err = - struct_span_err!(tcx.dcx(), drop_impl_span, E0366, "`Drop` impls cannot be specialized"); + let mut err = struct_span_code_err!( + tcx.dcx(), + drop_impl_span, + E0366, + "`Drop` impls cannot be specialized" + ); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { err.note(format!("`{arg}` is mentioned multiple times")) @@ -154,14 +158,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let item_span = tcx.def_span(adt_def_id); let self_descr = tcx.def_descr(adt_def_id.to_def_id()); guar = Some( - struct_span_err!( + struct_span_code_err!( tcx.dcx(), error.root_obligation.cause.span, E0367, "`Drop` impl requires `{root_predicate}` \ but the {self_descr} it is implemented for does not", ) - .span_note_mv(item_span, "the implementor must specify the same requirement") + .with_span_note(item_span, "the implementor must specify the same requirement") .emit(), ); } @@ -186,14 +190,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( } }; guar = Some( - struct_span_err!( + struct_span_code_err!( tcx.dcx(), error.origin().span(), E0367, "`Drop` impl requires `{outlives}` \ but the {self_descr} it is implemented for does not", ) - .span_note_mv(item_span, "the implementor must specify the same requirement") + .with_span_note(item_span, "the implementor must specify the same requirement") .emit(), ); } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index a5aedeb33ae96..7c3e296dfceec 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -8,7 +8,7 @@ use crate::errors::{ }; use hir::def_id::DefId; -use rustc_errors::{struct_span_err, DiagnosticMessage}; +use rustc_errors::{struct_span_code_err, DiagnosticMessage}; use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -29,8 +29,8 @@ fn equate_intrinsic_type<'tcx>( (own_counts, generics.span) } _ => { - struct_span_err!(tcx.dcx(), it.span, E0622, "intrinsic must be a function") - .span_label_mv(it.span, "expected a function") + struct_span_code_err!(tcx.dcx(), it.span, E0622, "intrinsic must be a function") + .with_span_label(it.span, "expected a function") .emit(); return; } @@ -552,7 +552,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)), _ => { let msg = format!("unrecognized platform-specific intrinsic function: `{name}`"); - tcx.dcx().struct_span_err(it.span, msg).emit(); + tcx.dcx().span_err(it.span, msg); return; } }; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 1979f52eda948..db619d5169e42 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -4,7 +4,7 @@ use rustc_hir as hir; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; -use rustc_span::{Symbol, DUMMY_SP}; +use rustc_span::Symbol; use rustc_target::abi::FieldIdx; use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; @@ -156,7 +156,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx .dcx() .struct_span_err(expr.span, msg) - .note_mv( + .with_note( "only integers, floats, SIMD vectors, pointers and function pointers \ can be used as arguments for inline assembly", ) @@ -171,7 +171,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx .dcx() .struct_span_err(expr.span, msg) - .note_mv(format!("`{ty}` does not implement the Copy trait")) + .with_note(format!("`{ty}` does not implement the Copy trait")) .emit(); } @@ -191,11 +191,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) - .span_label_mv(in_expr.span, format!("type `{in_expr_ty}`")) - .span_label_mv(expr.span, format!("type `{ty}`")) - .note_mv( + .with_span_label(in_expr.span, format!("type `{in_expr_ty}`")) + .with_span_label(expr.span, format!("type `{ty}`")) + .with_note( "asm inout arguments must have the same type, \ - unless they are both pointers or integers of the same size", + unless they are both pointers or integers of the same size", ) .emit(); } @@ -242,7 +242,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx .dcx() .struct_span_err(expr.span, msg) - .note_mv(format!( + .with_note(format!( "this is required to use type `{}` with register class `{}`", ty, reg_class.name(), @@ -294,7 +294,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) { let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id()); let Some(asm_arch) = self.tcx.sess.asm_arch else { - self.tcx.dcx().span_delayed_bug(DUMMY_SP, "target architecture does not support asm"); + self.tcx.dcx().delayed_bug("target architecture does not support asm"); return; }; for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { @@ -325,7 +325,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.tcx.dcx().struct_span_err(*op_sp, msg).emit(); + self.tcx.dcx().span_err(*op_sp, msg); continue; } } @@ -364,7 +364,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.tcx.dcx().struct_span_err(*op_sp, msg).emit(); + self.tcx.dcx().span_err(*op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -378,7 +378,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::(), ); - self.tcx.dcx().struct_span_err(*op_sp, msg).emit(); + self.tcx.dcx().span_err(*op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -459,11 +459,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { self.tcx .dcx() .struct_span_err(*op_sp, "invalid `sym` operand") - .span_label_mv( + .with_span_label( self.tcx.def_span(anon_const.def_id), format!("is {} `{}`", ty.kind().article(), ty), ) - .help_mv( + .with_help( "`sym` operands must refer to either a function or a static", ) .emit(); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index ac0c715c6b308..3b05eaedf342b 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -78,7 +78,7 @@ use std::num::NonZeroU32; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::ErrorGuaranteed; -use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_code_err, Diagnostic, DiagnosticBuilder}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 67ec2c3e5ea82..59c7222714407 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -3,7 +3,9 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{ + pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, +}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::lang_items::LangItem; @@ -200,8 +202,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() res = Err(tcx .dcx() .struct_span_err(sp, "impls of auto traits cannot be default") - .span_labels_mv(impl_.defaultness_span, "default because of this") - .span_label_mv(sp, "auto trait") + .with_span_labels(impl_.defaultness_span, "default because of this") + .with_span_label(sp, "auto trait") .emit()); } // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. @@ -217,7 +219,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() if let hir::Defaultness::Default { .. } = impl_.defaultness { let mut spans = vec![span]; spans.extend(impl_.defaultness_span); - res = Err(struct_span_err!( + res = Err(struct_span_code_err!( tcx.dcx(), spans, E0750, @@ -502,19 +504,18 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { gat_item_hir.span, format!("missing required bound{} on `{}`", plural, gat_item_hir.ident), ) - .span_suggestion_mv( + .with_span_suggestion( gat_item_hir.generics.tail_span_for_predicate_suggestion(), format!("add the required where clause{plural}"), suggestion, Applicability::MachineApplicable, ) - .note_mv(format!( + .with_note(format!( "{bound} currently required to ensure that impls have maximum flexibility" )) - .note_mv( + .with_note( "we are soliciting feedback, see issue #87479 \ - \ - for more information", + for more information", ) .emit(); } @@ -837,8 +838,8 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem trait_should_be_self, "associated item referring to unboxed trait object for its own trait", ) - .span_label_mv(trait_name.span, "in this trait") - .multipart_suggestion_mv( + .with_span_label(trait_name.span, "in this trait") + .with_multipart_suggestion( "you might have meant to use `Self` to refer to the implementing type", sugg, Applicability::MachineApplicable, @@ -1116,7 +1117,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuarant || matches!(trait_def.specialization_kind, TraitSpecializationKind::Marker) { for associated_def_id in &*tcx.associated_item_def_ids(def_id) { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(*associated_def_id), E0714, @@ -1598,7 +1599,7 @@ fn check_method_receiver<'tcx>( the `arbitrary_self_types` feature", ), ) - .help_mv(HELP_FOR_SELF_TYPE) + .with_help(HELP_FOR_SELF_TYPE) .emit() } else { // Report error; would not have worked with `arbitrary_self_types`. @@ -1610,9 +1611,9 @@ fn check_method_receiver<'tcx>( } fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed { - struct_span_err!(tcx.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}") - .note_mv("type of `self` must be `Self` or a type that dereferences to it") - .help_mv(HELP_FOR_SELF_TYPE) + struct_span_code_err!(tcx.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}") + .with_note("type of `self` must be `Self` or a type that dereferences to it") + .with_help(HELP_FOR_SELF_TYPE) .emit() } @@ -1920,8 +1921,8 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error } fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> { - struct_span_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used") - .span_label_mv(span, "unused parameter") + struct_span_code_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used") + .with_span_label(span, "unused parameter") } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 8f54bf00528cb..4c3455c7240f6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -70,15 +70,15 @@ impl<'tcx> InherentOverlapChecker<'tcx> { match seen_items.entry(norm_ident) { Entry::Occupied(entry) => { let former = entry.get(); - struct_span_err!( + struct_span_code_err!( self.tcx.dcx(), span, E0592, "duplicate definitions with name `{}`", ident, ) - .span_label_mv(span, format!("duplicate definitions for `{ident}`")) - .span_label_mv(*former, format!("other definition for `{ident}`")) + .with_span_label(span, format!("duplicate definitions for `{ident}`")) + .with_span_label(*former, format!("other definition for `{ident}`")) .emit(); } Entry::Vacant(entry) => { @@ -104,7 +104,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { if let Some(item2) = collision { let name = item1.ident(self.tcx).normalize_to_macros_2_0(); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.tcx.dcx(), self.tcx.def_span(item1.def_id), E0592, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 3d56f8fd44ea2..561a254e89ef7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -6,7 +6,7 @@ // mappings. That mapping code resides here. use crate::errors; -use rustc_errors::{error_code, struct_span_err}; +use rustc_errors::{error_code, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; @@ -45,7 +45,7 @@ fn enforce_trait_manually_implementable( // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]` if tcx.trait_def(trait_def_id).deny_explicit_impl { let trait_name = tcx.item_name(trait_def_id); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), impl_header_span, E0322, @@ -88,7 +88,7 @@ fn enforce_empty_impls_for_marker_traits( return; } - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(impl_def_id), E0715, @@ -173,7 +173,7 @@ fn check_object_overlap<'tcx>( let mut supertrait_def_ids = traits::supertrait_def_ids(tcx, component_def_id); if supertrait_def_ids.any(|d| d == trait_def_id) { let span = tcx.def_span(impl_def_id); - struct_span_err!( + struct_span_code_err!( tcx.dcx(), span, E0371, @@ -181,7 +181,7 @@ fn check_object_overlap<'tcx>( trait_ref.self_ty(), tcx.def_path_str(trait_def_id) ) - .span_label_mv( + .with_span_label( span, format!( "`{}` automatically implements trait `{}`", diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 272c13b4c1c8e..7b146573a1b3b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -1,7 +1,7 @@ //! Unsafety checker: every impl either implements a trait defined in this //! crate or pertains to a type defined in this crate. -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::Unsafety; use rustc_middle::ty::TyCtxt; @@ -18,14 +18,14 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) { (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0199, "implementing the trait `{}` is not unsafe", trait_ref.print_trait_sugared() ) - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( item.span.with_hi(item.span.lo() + rustc_span::BytePos(7)), "remove `unsafe` from this trait implementation", "", @@ -35,20 +35,20 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { } (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0200, "the trait `{}` requires an `unsafe impl` declaration", trait_ref.print_trait_sugared() ) - .note_mv(format!( + .with_note(format!( "the trait `{}` enforces invariants that the compiler can't check. \ Review the trait documentation and make sure this implementation \ upholds those invariants before adding the `unsafe` keyword", trait_ref.print_trait_sugared() )) - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( item.span.shrink_to_lo(), "add `unsafe` to this trait implementation", "unsafe ", @@ -58,20 +58,20 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { } (Unsafety::Normal, Some(attr_name), Unsafety::Normal, hir::ImplPolarity::Positive) => { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0569, "requires an `unsafe impl` declaration due to `#[{}]` attribute", attr_name ) - .note_mv(format!( + .with_note(format!( "the trait `{}` enforces invariants that the compiler can't check. \ Review the trait documentation and make sure this implementation \ upholds those invariants before adding the `unsafe` keyword", trait_ref.print_trait_sugared() )) - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( item.span.shrink_to_lo(), "add `unsafe` to this trait implementation", "unsafe ", diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 0a13949a68821..c9f89a0c3ef32 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -642,7 +642,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure().generics_of(def_id); tcx.ensure().type_of(def_id); tcx.ensure().predicates_of(def_id); - if !is_suggestable_infer_ty(ty) { + if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_item(it); placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr()); @@ -674,7 +674,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { hir::TraitItemKind::Const(ty, body_id) => { tcx.ensure().type_of(def_id); if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType) - && !(is_suggestable_infer_ty(ty) && body_id.is_some()) + && !(ty.is_suggestable_infer_ty() && body_id.is_some()) { // Account for `const C: _;`. let mut visitor = HirPlaceholderCollector::default(); @@ -726,7 +726,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { } hir::ImplItemKind::Const(ty, _) => { // Account for `const T: _ = ..;` - if !is_suggestable_infer_ty(ty) { + if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_impl_item(impl_item); placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant"); @@ -1054,48 +1054,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { } } -fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool { - generic_args.iter().any(|arg| match arg { - hir::GenericArg::Type(ty) => is_suggestable_infer_ty(ty), - hir::GenericArg::Infer(_) => true, - _ => false, - }) -} - -/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to -/// use inference to provide suggestions for the appropriate type if possible. -fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { - debug!(?ty); - use hir::TyKind::*; - match &ty.kind { - Infer => true, - Slice(ty) => is_suggestable_infer_ty(ty), - Array(ty, length) => { - is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _)) - } - Tup(tys) => tys.iter().any(is_suggestable_infer_ty), - Ptr(mut_ty) | Ref(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), - OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args), - Path(hir::QPath::TypeRelative(ty, segment)) => { - is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args) - } - Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => { - ty_opt.is_some_and(is_suggestable_infer_ty) - || segments.iter().any(|segment| are_suggestable_generic_args(segment.args().args)) - } - _ => false, - } -} - -pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> { - if let hir::FnRetTy::Return(ty) = output { - if is_suggestable_infer_ty(ty) { - return Some(*ty); - } - } - None -} - #[instrument(level = "debug", skip(tcx))] fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder> { use rustc_hir::Node::*; @@ -1188,7 +1146,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( ) -> ty::PolyFnSig<'tcx> { let hir_id = tcx.local_def_id_to_hir_id(def_id); - match get_infer_ret_ty(&sig.decl.output) { + match sig.decl.output.get_infer_ret_ty() { Some(ty) => { let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; // Typeck doesn't expect erased regions to be returned from `type_of`. diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 61bb4235139db..3d8390d1946ea 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -8,7 +8,7 @@ use rustc_ast::walk_list; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_session::lint; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use std::fmt; use crate::errors; @@ -335,13 +335,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // though this may happen when we call `poly_trait_ref_binder_info` with // an (erroneous, #113423) associated return type bound in an impl header. if !supertrait_bound_vars.is_empty() { - self.tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!( - "found supertrait lifetimes without a binder to append \ + self.tcx.dcx().delayed_bug(format!( + "found supertrait lifetimes without a binder to append \ them to: {supertrait_bound_vars:?}" - ), - ); + )); } break (vec![], BinderScopeType::Normal); } @@ -737,7 +734,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // Ensure that the parent of the def is an item, not HRTB let parent_id = self.tcx.hir().parent_id(hir_id); if !parent_id.is_owner() { - struct_span_err!( + struct_span_code_err!( self.tcx.dcx(), lifetime.ident.span, E0657, @@ -754,7 +751,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { lifetime.ident.span, "higher kinded lifetime bounds on nested opaque types are not supported yet", ) - .span_note_mv(self.tcx.def_span(def_id), "lifetime declared here") + .with_span_note(self.tcx.def_span(def_id), "lifetime declared here") .emit(); self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 55720e6d2aa4f..3ceea3dc7ae3f 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -9,8 +9,8 @@ use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, Ty use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; +use super::bad_placeholder; use super::ItemCtxt; -use super::{bad_placeholder, is_suggestable_infer_ty}; pub use opaque::test_opaque_hidden_types; mod opaque; @@ -368,7 +368,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder body_id .and_then(|body_id| { - is_suggestable_infer_ty(ty).then(|| { + ty.is_suggestable_infer_ty().then(|| { infer_placeholder_type( tcx, def_id, @@ -392,7 +392,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder { - if is_suggestable_infer_ty(ty) { + if ty.is_suggestable_infer_ty() { infer_placeholder_type( tcx, def_id, @@ -416,7 +416,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder match item.kind { ItemKind::Static(ty, .., body_id) => { - if is_suggestable_infer_ty(ty) { + if ty.is_suggestable_infer_ty() { infer_placeholder_type( tcx, def_id, @@ -430,7 +430,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder { - if is_suggestable_infer_ty(ty) { + if ty.is_suggestable_infer_ty() { infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant") } else { icx.to_ty(ty) @@ -603,6 +603,8 @@ fn infer_placeholder_type<'a>( } err.emit(); + // diagnostic stashing loses the information of whether something is a hard error. + Ty::new_error_with_message(tcx, span, "ItemNoType is a hard error") } None => { let mut diag = bad_placeholder(tcx, vec![span], kind); @@ -623,15 +625,9 @@ fn infer_placeholder_type<'a>( } } - diag.emit(); + Ty::new_error(tcx, diag.emit()) } } - - // Typeck doesn't expect erased regions to be returned from `type_of`. - tcx.fold_regions(ty, |r, _| match *r { - ty::ReErased => tcx.lifetimes.re_static, - _ => r, - }) } fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index da7279967dac1..1f7ca48234a24 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -134,6 +134,21 @@ impl TaitConstraintLocator<'_> { debug!("no constraint: no typeck results"); return; } + + if let Some(hir_sig) = self.tcx.hir_node_by_def_id(item_def_id).fn_decl() { + if hir_sig.output.get_infer_ret_ty().is_some() { + let guar = self.tcx.dcx().span_delayed_bug( + hir_sig.output.span(), + "inferring return types and opaque types do not mix well", + ); + self.found = Some(ty::OpaqueHiddenType { + span: DUMMY_SP, + ty: Ty::new_error(self.tcx, guar), + }); + return; + } + } + // Calling `mir_borrowck` can lead to cycle errors through // const-checking, avoid calling it if we don't have to. // ```rust diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index ff5fff9363f35..3f9b1f384d790 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -12,7 +12,7 @@ use crate::constrained_generic_params as cgp; use min_specialization::check_min_specialization; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_middle::query::Providers; @@ -170,7 +170,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) } fn report_unused_parameter(tcx: TyCtxt<'_>, span: Span, kind: &str, name: Symbol) { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), span, E0207, diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 04c42b4b2e632..6657e3fd872fa 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> { let span = self.path_segment.ident.span; let msg = self.create_error_message(); - self.tcx.dcx().struct_span_err(span, msg).code_mv(self.code()) + self.tcx.dcx().struct_span_err(span, msg).with_code(self.code()) } /// Builds the `expected 1 type argument / supplied 2 type arguments` message. diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index fc61467df0142..1a4e03d50cae0 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -402,7 +402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_expr.span, format!("evaluate({predicate:?}) = {result:?}"), ) - .span_label_mv(predicate_span, "predicate") + .with_span_label(predicate_span, "predicate") .emit(); } } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 0a9f2a27cb83f..a720a858f3c13 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -269,7 +269,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } CastError::NeedViaInt => { make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx) - .help_mv("cast through an integer first") + .with_help("cast through an integer first") .emit(); } CastError::IllegalCast => { @@ -277,7 +277,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } CastError::DifferingKinds => { make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx) - .note_mv("vtable kinds may not match") + .with_note("vtable kinds may not match") .emit(); } CastError::CastToBool => { @@ -512,7 +512,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.cast_ty, fcx, ) - .note_mv("cannot cast an enum with a non-exhaustive variant when it's defined in another crate") + .with_note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate") .emit(); } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 1aa25a5bd7f76..0b266202b2674 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -36,7 +36,7 @@ //! ``` use crate::FnCtxt; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; +use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; @@ -1571,7 +1571,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut visitor = CollectRetsVisitor { ret_exprs: vec![] }; match *cause.code() { ObligationCauseCode::ReturnNoExpression => { - err = struct_span_err!( + err = struct_span_code_err!( fcx.dcx(), cause.span, E0069, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7617f03fcf290..fdad998c451f1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -25,7 +25,7 @@ use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ - pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, + pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed, StashKey, }; use rustc_hir as hir; @@ -1760,7 +1760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Make sure the programmer specified correct number of fields. if adt_kind == AdtKind::Union { if ast_fields.len() != 1 { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), span, E0784, @@ -1967,7 +1967,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0063, @@ -2194,7 +2194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = self.err_ctxt().type_error_struct_with_diag( field.ident.span, |actual| match ty.kind() { - ty::Adt(adt, ..) if adt.is_enum() => struct_span_err!( + ty::Adt(adt, ..) if adt.is_enum() => struct_span_code_err!( self.dcx(), field.ident.span, E0559, @@ -2204,7 +2204,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant.name, field.ident ), - _ => struct_span_err!( + _ => struct_span_code_err!( self.dcx(), field.ident.span, E0560, @@ -2832,13 +2832,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn private_field_err(&self, field: Ident, base_did: DefId) -> DiagnosticBuilder<'_> { let struct_path = self.tcx().def_path_str(base_did); let kind_name = self.tcx().def_descr(base_did); - struct_span_err!( + struct_span_code_err!( self.dcx(), field.span, E0616, "field `{field}` of {kind_name} `{struct_path}` is private", ) - .span_label_mv(field.span, "private field") + .with_span_label(field.span, "private field") } pub(crate) fn get_field_candidates_considering_privacy( @@ -3181,7 +3181,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !is_input && !expr.is_syntactic_place_expr() { self.dcx() .struct_span_err(expr.span, "invalid asm output") - .span_label_mv(expr.span, "cannot assign to this expression") + .with_span_label(expr.span, "cannot assign to this expression") .emit(); } @@ -3282,7 +3282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0599, "no variant named `{ident}` found for enum `{container}`", ) - .span_label_mv(field.span, "variant not found") + .with_span_label(field.span, "variant not found") .emit(); break; }; @@ -3294,7 +3294,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0795, "`{ident}` is an enum variant; expected field at end of `offset_of`", ) - .span_label_mv(field.span, "enum variant") + .with_span_label(field.span, "enum variant") .emit(); break; }; @@ -3313,8 +3313,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0609, "no field named `{subfield}` on enum variant `{container}::{ident}`", ) - .span_label_mv(field.span, "this enum variant...") - .span_label_mv(subident.span, "...does not have this field") + .with_span_label(field.span, "this enum variant...") + .with_span_label(subident.span, "...does not have this field") .emit(); break; }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index da6f2042c110d..8cd5ed3494b18 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -6,7 +6,8 @@ use crate::method::MethodCallee; use crate::TupleArgumentsFlag::*; use crate::{errors, Expectation::*}; use crate::{ - struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy, TupleArgumentsFlag, + struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy, + TupleArgumentsFlag, }; use rustc_ast as ast; use rustc_data_structures::fx::FxIndexSet; @@ -204,7 +205,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // Otherwise, there's a mismatch, so clear out what we're expecting, and set // our input types to err_args so we don't blow up the error messages - struct_span_err!( + struct_span_code_err!( tcx.dcx(), call_span, E0059, @@ -807,7 +808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut err = if formal_and_expected_inputs.len() == provided_args.len() { - struct_span_err!( + struct_span_code_err!( tcx.dcx(), full_call_span, E0308, @@ -827,7 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pluralize!("was", provided_args.len()) ), ) - .code_mv(DiagnosticId::Error(err_code.to_owned())) + .with_code(DiagnosticId::Error(err_code.to_owned())) }; // As we encounter issues, keep track of what we want to provide for the suggestion @@ -1378,14 +1379,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // (issue #88844). guar } - _ => struct_span_err!( + _ => struct_span_code_err!( self.dcx(), path_span, E0071, "expected struct, variant or union type, found {}", ty.normalized.sort_string(self.tcx) ) - .span_label_mv(path_span, "not a struct") + .with_span_label(path_span, "not a struct") .emit(), }) } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 8bffd2dfc70a1..e087733130e33 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -1,5 +1,5 @@ use hir::HirId; -use rustc_errors::struct_span_err; +use rustc_errors::struct_span_code_err; use rustc_hir as hir; use rustc_index::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; @@ -73,10 +73,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) { - struct_span_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") - .note_mv(format!("source type: {from}")) - .note_mv(format!("target type: {to}")) - .help_mv("cast with `as` to a pointer instead") + struct_span_code_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") + .with_note(format!("source type: {from}")) + .with_note(format!("target type: {to}")) + .with_help("cast with `as` to a pointer instead") .emit(); return; } @@ -112,7 +112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(err) => err.to_string(), }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), span, E0512, diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index ffae08d0f27cc..36dd06d944c4e 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -52,7 +52,7 @@ use crate::expectation::Expectation; use crate::fn_ctxt::RawTy; use crate::gather_locals::GatherLocalsVisitor; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed}; +use rustc_errors::{struct_span_code_err, DiagnosticId, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; @@ -72,7 +72,7 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } #[macro_export] macro_rules! type_error_struct { ($dcx:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({ - let mut err = rustc_errors::struct_span_err!($dcx, $span, $code, $($message)*); + let mut err = rustc_errors::struct_span_code_err!($dcx, $span, $code, $($message)*); if $typ.references_error() { err.downgrade_to_delayed_bug(); @@ -181,7 +181,7 @@ fn typeck_with_fallback<'tcx>( let mut fcx = FnCtxt::new(&inh, param_env, def_id); if let Some(hir::FnSig { header, decl, .. }) = fn_sig { - let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() { + let fn_sig = if decl.output.get_infer_ret_ty().is_some() { fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None) } else { tcx.fn_sig(def_id).instantiate_identity() @@ -369,14 +369,14 @@ fn report_unexpected_variant_res( let err = tcx .dcx() .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`")) - .code_mv(DiagnosticId::Error(err_code.into())); + .with_code(DiagnosticId::Error(err_code.into())); match res { Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => { let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html"; - err.span_label_mv(span, "`fn` calls are not allowed in patterns") - .help_mv(format!("for more information, visit {patterns_url}")) + err.with_span_label(span, "`fn` calls are not allowed in patterns") + .with_help(format!("for more information, visit {patterns_url}")) } - _ => err.span_label_mv(span, format!("not a {expected}")), + _ => err.with_span_label(span, format!("not a {expected}")), } .emit() } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 58db2f10bd087..1f01c6b7406b7 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::StashKey; use rustc_errors::{ - pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan, + pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan, }; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -148,7 +148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } MethodError::Ambiguity(mut sources) => { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), item_name.span, E0034, @@ -171,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { let kind = self.tcx.def_kind_descr(kind, def_id); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), item_name.span, E0624, @@ -263,8 +263,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'_> { let mut file = None; let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file); - let mut err = - struct_span_err!(self.dcx(), rcvr_expr.span, E0599, "cannot write into `{}`", ty_str); + let mut err = struct_span_code_err!( + self.dcx(), + rcvr_expr.span, + E0599, + "cannot write into `{}`", + ty_str + ); err.span_note( rcvr_expr.span, "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", @@ -1836,7 +1841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !actual.has_concrete_skeleton() && let SelfSource::MethodCall(expr) = source { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), span, E0689, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 3b5226c641431..ee411f8ed5f1c 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -4,7 +4,7 @@ use super::method::MethodCallee; use super::{has_expected_num_generic_args, FnCtxt}; use crate::Expectation; use rustc_ast as ast; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder}; use rustc_hir as hir; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::traits::ObligationCauseCode; @@ -306,7 +306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|def_id| with_no_trimmed_paths!(self.tcx.def_path_str(def_id))); let (mut err, output_def_id) = match is_assign { IsAssign::Yes => { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), expr.span, E0368, @@ -370,7 +370,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .cloned() }); - let mut err = struct_span_err!(self.dcx(), op.span, E0369, "{message}"); + let mut err = + struct_span_code_err!(self.dcx(), op.span, E0369, "{message}"); if !lhs_expr.span.eq(&rhs_expr.span) { err.span_label(lhs_expr.span, lhs_ty.to_string()); err.span_label(rhs_expr.span, rhs_ty.to_string()); @@ -788,7 +789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(errors) => { let actual = self.resolve_vars_if_possible(operand_ty); let guar = actual.error_reported().err().unwrap_or_else(|| { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), ex.span, E0600, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 4ac85cce292f0..95813cb68a664 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -3,7 +3,7 @@ use crate::{errors, FnCtxt, RawTy}; use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{ - pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, + pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, }; use rustc_hir as hir; @@ -546,7 +546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (_, Some((true, _, sp))) => sp, _ => span_bug!(span, "emit_err_pat_range: no side failed or exists but still error?"), }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0029, @@ -837,7 +837,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This is "x = SomeTrait" being reduced from // "let &x = &SomeTrait" or "let box x = Box", an error. let type_str = self.ty_to_string(expected); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0033, @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let last_field_def_span = *field_def_spans.last().unwrap(); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), MultiSpan::from_spans(subpat_spans), E0023, @@ -1516,7 +1516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { let path = rustc_hir_pretty::qpath_to_string(qpath); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), pat.span, E0769, @@ -1541,13 +1541,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sp_comma = sm.end_point(pat.span.with_hi(sp_brace.hi())); let sugg = if no_fields || sp_brace != sp_comma { ".. }" } else { ", .. }" }; - struct_span_err!( + struct_span_code_err!( self.dcx(), pat.span, E0638, "`..` required with {descr} marked as non-exhaustive", ) - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( sp_comma, "add `..` at the end of the field list to ignore all other fields", sugg, @@ -1562,15 +1562,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ident: Ident, other_field: Span, ) -> ErrorGuaranteed { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0025, "field `{}` bound multiple times in the pattern", ident ) - .span_label_mv(span, format!("multiple uses of `{ident}` in pattern")) - .span_label_mv(other_field, format!("first use of `{ident}`")) + .with_span_label(span, format!("multiple uses of `{ident}` in pattern")) + .with_span_label(other_field, format!("first use of `{ident}`")) .emit() } @@ -1601,7 +1601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }; let spans = inexistent_fields.iter().map(|field| field.ident.span).collect::>(); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), spans, E0026, @@ -1698,7 +1698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let path = rustc_hir_pretty::qpath_to_string(qpath); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), pat.span, E0769, @@ -1876,7 +1876,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .join(", "); format!("fields {fields}{inaccessible}") }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), pat.span, E0027, @@ -2226,7 +2226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_len: u64, size: u64, ) -> ErrorGuaranteed { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0527, @@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pluralize!(min_len), size, ) - .span_label_mv(span, format!("expected {} element{}", size, pluralize!(size))) + .with_span_label(span, format!("expected {} element{}", size, pluralize!(size))) .emit() } @@ -2245,7 +2245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_len: u64, size: u64, ) -> ErrorGuaranteed { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0528, @@ -2254,7 +2254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pluralize!(min_len), size, ) - .span_label_mv( + .with_span_label( span, format!("pattern cannot match array of {} element{}", size, pluralize!(size),), ) @@ -2262,7 +2262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn error_scrutinee_unfixed_length(&self, span: Span) -> ErrorGuaranteed { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0730, @@ -2277,7 +2277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>, ) -> ErrorGuaranteed { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0529, diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 3825c513ef3f0..d626176377283 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -336,10 +336,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.span, "not automatically applying `DerefMut` on `ManuallyDrop` union field", ) - .help_mv( + .with_help( "writing to this reference calls the destructor for the old value", ) - .help_mv("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor") + .with_help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor") .emit(); } } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 2c6ae91786d10..e18b1365d9c02 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -273,7 +273,7 @@ pub(crate) fn prepare_session_directory( debug!("successfully copied data from: {}", source_directory.display()); if !allows_links { - sess.dcx().emit_warning(errors::HardLinkFailed { path: &session_dir }); + sess.dcx().emit_warn(errors::HardLinkFailed { path: &session_dir }); } sess.init_incr_comp_session(session_dir, directory_lock); @@ -288,7 +288,7 @@ pub(crate) fn prepare_session_directory( // Try to remove the session directory we just allocated. We don't // know if there's any garbage in it from the failed copy action. if let Err(err) = safe_remove_dir_all(&session_dir) { - sess.dcx().emit_warning(errors::DeletePartial { path: &session_dir, err }); + sess.dcx().emit_warn(errors::DeletePartial { path: &session_dir, err }); } delete_session_dir_lock_file(sess, &lock_file_path); @@ -322,7 +322,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option) { ); if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) { - sess.dcx().emit_warning(errors::DeleteFull { path: &incr_comp_session_dir, err }); + sess.dcx().emit_warn(errors::DeleteFull { path: &incr_comp_session_dir, err }); } let lock_file_path = lock_file_path(&*incr_comp_session_dir); @@ -365,7 +365,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option) { } Err(e) => { // Warn about the error. However, no need to abort compilation now. - sess.dcx().emit_warning(errors::Finalize { path: &incr_comp_session_dir, err: e }); + sess.dcx().emit_warn(errors::Finalize { path: &incr_comp_session_dir, err: e }); debug!("finalize_session_directory() - error, marking as invalid"); // Drop the file lock, so we can garage collect @@ -500,7 +500,7 @@ fn lock_directory( fn delete_session_dir_lock_file(sess: &Session, lock_file_path: &Path) { if let Err(err) = safe_remove_file(lock_file_path) { - sess.dcx().emit_warning(errors::DeleteLock { path: lock_file_path, err }); + sess.dcx().emit_warn(errors::DeleteLock { path: lock_file_path, err }); } } @@ -724,7 +724,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result< if !lock_file_to_session_dir.items().any(|(_, dir)| *dir == directory_name) { let path = crate_directory.join(directory_name); if let Err(err) = safe_remove_dir_all(&path) { - sess.dcx().emit_warning(errors::InvalidGcFailed { path: &path, err }); + sess.dcx().emit_warn(errors::InvalidGcFailed { path: &path, err }); } } } @@ -830,7 +830,7 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result< debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); if let Err(err) = safe_remove_dir_all(&path) { - sess.dcx().emit_warning(errors::FinalizedGcFailed { path: &path, err }); + sess.dcx().emit_warn(errors::FinalizedGcFailed { path: &path, err }); } else { delete_session_dir_lock_file(sess, &lock_file_path(&path)); } @@ -848,7 +848,7 @@ fn delete_old(sess: &Session, path: &Path) { debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); if let Err(err) = safe_remove_dir_all(path) { - sess.dcx().emit_warning(errors::SessionGcFailed { path: path, err }); + sess.dcx().emit_warn(errors::SessionGcFailed { path: path, err }); } else { delete_session_dir_lock_file(sess, &lock_file_path(path)); } diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index ce8f5bb69ae3b..96bfe766c20f5 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -51,7 +51,7 @@ impl LoadResult { match self { LoadResult::LoadDepGraph(path, err) => { - sess.dcx().emit_warning(errors::LoadDepGraph { path, err }); + sess.dcx().emit_warn(errors::LoadDepGraph { path, err }); Default::default() } LoadResult::DataOutOfDate => { diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 1450d8a99abbc..906233ef53ec8 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -30,7 +30,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( let _ = saved_files.insert(ext.to_string(), file_name); } Err(err) => { - sess.dcx().emit_warning(errors::CopyWorkProductToCache { + sess.dcx().emit_warn(errors::CopyWorkProductToCache { from: path, to: &path_in_incr_dir, err, @@ -50,7 +50,7 @@ pub(crate) fn delete_workproduct_files(sess: &Session, work_product: &WorkProduc for (_, path) in work_product.saved_files.items().into_sorted_stable_ord() { let path = in_incr_comp_dir_sess(sess, path); if let Err(err) = std_fs::remove_file(&path) { - sess.dcx().emit_warning(errors::DeleteWorkProduct { path: &path, err }); + sess.dcx().emit_warn(errors::DeleteWorkProduct { path: &path, err }); } } } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index c156c13c96205..e4b37f05b778f 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -192,10 +192,10 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { // rust-lang/rust#57464: `impl Trait` can leak local // scopes (in manner violating typeck). Therefore, use // `span_delayed_bug` to allow type error over an ICE. - canonicalizer.tcx.dcx().span_delayed_bug( - rustc_span::DUMMY_SP, - format!("unexpected region in query response: `{r:?}`"), - ); + canonicalizer + .tcx + .dcx() + .delayed_bug(format!("unexpected region in query response: `{r:?}`")); r } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b1c360b61cb69..875e94fcd9f16 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -60,8 +60,8 @@ use crate::traits::{ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, - DiagnosticStyledString, ErrorGuaranteed, IntoDiagnosticArg, + error_code, pluralize, struct_span_code_err, Applicability, DiagCtxt, Diagnostic, + DiagnosticBuilder, DiagnosticStyledString, ErrorGuaranteed, IntoDiagnosticArg, }; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -2348,11 +2348,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { GenericKind::Param(ref p) => format!("the parameter type `{p}`"), GenericKind::Placeholder(ref p) => format!("the placeholder type `{p:?}`"), GenericKind::Alias(ref p) => match p.kind(self.tcx) { - ty::AliasKind::Projection | ty::AliasKind::Inherent => { + ty::Projection | ty::Inherent => { format!("the associated type `{p}`") } - ty::AliasKind::Weak => format!("the type alias `{p}`"), - ty::AliasKind::Opaque => format!("the opaque type `{p}`"), + ty::Weak => format!("the type alias `{p}`"), + ty::Opaque => format!("the opaque type `{p}`"), }, }; @@ -2780,7 +2780,7 @@ impl<'tcx> InferCtxt<'tcx> { infer::Nll(..) => bug!("NLL variable found in lexical phase"), }; - struct_span_err!( + struct_span_code_err!( self.tcx.dcx(), var_origin.span(), E0495, diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 77a0accf80bb6..02200d6a4aaf5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -368,7 +368,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { let span = *span; self.report_concrete_failure(placeholder_origin, sub, sup) - .span_note_mv(span, "the lifetime requirement is introduced here") + .with_span_note(span, "the lifetime requirement is introduced here") } else { unreachable!( "control flow ensures we have a `BindingObligation` or `ExprBindingObligation` here..." diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fa694f09f178d..fcc94687ed293 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -38,7 +38,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtx use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid}; use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef}; use rustc_span::symbol::Symbol; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use std::cell::{Cell, RefCell}; use std::fmt; @@ -1434,10 +1434,8 @@ impl<'tcx> InferCtxt<'tcx> { bug!("`{value:?}` is not fully resolved"); } if value.has_infer_regions() { - let guar = self - .tcx - .dcx() - .span_delayed_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved")); + let guar = + self.tcx.dcx().delayed_bug(format!("`{value:?}` is not fully resolved")); Ok(self.tcx.fold_regions(value, |re, _| { if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re } })) diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index c91eb7eddd846..6a684dba8dec5 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -1,6 +1,5 @@ use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; -use rustc_span::DUMMY_SP; use crate::infer::{InferCtxtUndoLogs, UndoLog}; @@ -40,9 +39,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { impl<'tcx> Drop for OpaqueTypeStorage<'tcx> { fn drop(&mut self) { if !self.opaque_types.is_empty() { - ty::tls::with(|tcx| { - tcx.dcx().span_delayed_bug(DUMMY_SP, format!("{:?}", self.opaque_types)) - }); + ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{:?}", self.opaque_types))); } } } diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index dd364312cade2..7a85268492b43 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -175,10 +175,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // ignore this, we presume it will yield an error // later, since if a type variable is not resolved by // this point it never will be - self.tcx.dcx().span_delayed_bug( - rustc_span::DUMMY_SP, - format!("unresolved inference variable in outlives: {v:?}"), - ); + self.tcx + .dcx() + .delayed_bug(format!("unresolved inference variable in outlives: {v:?}")); // add a bound that never holds VerifyBound::AnyBound(vec![]) } diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 8b31a1118cb75..4b254fc7df518 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -180,10 +180,9 @@ impl<'tcx> InferCtxt<'tcx> { &mut OriginalQueryValues::default(), ); self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { - self.tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("cannot relate consts of different types (a={a:?}, b={b:?})",), - ) + self.tcx.dcx().delayed_bug(format!( + "cannot relate consts of different types (a={a:?}, b={b:?})", + )) }) }); @@ -511,7 +510,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { )); } else { match a_ty.kind() { - &ty::Alias(ty::AliasKind::Projection, data) => { + &ty::Alias(ty::Projection, data) => { // FIXME: This does not handle subtyping correctly, we could // instead create a new inference variable for `a_ty`, emitting // `Projection(a_ty, a_infer)` and `a_infer <: b_ty`. @@ -523,10 +522,9 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { )) } // The old solver only accepts projection predicates for associated types. - ty::Alias( - ty::AliasKind::Inherent | ty::AliasKind::Weak | ty::AliasKind::Opaque, - _, - ) => return Err(TypeError::CyclicTy(a_ty)), + ty::Alias(ty::Inherent | ty::Weak | ty::Opaque, _) => { + return Err(TypeError::CyclicTy(a_ty)); + } _ => bug!("generalizated `{a_ty:?} to infer, not an alias"), } } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index e91411ffc7a3b..6f218019dee5a 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -2,7 +2,7 @@ use super::ObjectSafetyViolation; use crate::infer::InferCtxt; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, MultiSpan}; +use rustc_errors::{struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Map; @@ -20,7 +20,7 @@ impl<'tcx> InferCtxt<'tcx> { trait_item_def_id: DefId, requirement: &dyn fmt::Display, ) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.tcx.dcx(), error_span, E0276, @@ -52,7 +52,7 @@ pub fn report_object_safety_error<'tcx>( hir::Node::Item(item) => Some(item.ident.span), _ => None, }); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( tcx.dcx(), span, E0038, diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 7458be2c86da7..8c7e49b51f9b2 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -9,7 +9,7 @@ //! The functions in this file should fall back to the default set in their //! origin crate when the `TyCtxt` is not present in TLS. -use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS}; +use rustc_errors::{Diagnostic, TRACK_DIAGNOSTIC}; use rustc_middle::dep_graph::{DepNodeExt, TaskDepsRef}; use rustc_middle::ty::tls; use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug; @@ -103,5 +103,5 @@ pub fn setup_callbacks() { .swap(&(dep_kind_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); rustc_query_system::dep_graph::dep_node::DEP_NODE_DEBUG .swap(&(dep_node_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); - TRACK_DIAGNOSTICS.swap(&(track_diagnostic as _)); + TRACK_DIAGNOSTIC.swap(&(track_diagnostic as _)); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ce76c2cba939c..9795640412069 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -254,7 +254,7 @@ fn configure_and_expand( } if is_proc_macro_crate && sess.panic_strategy() == PanicStrategy::Abort { - sess.dcx().emit_warning(errors::ProcMacroCratePanicAbort); + sess.dcx().emit_warn(errors::ProcMacroCratePanicAbort); } sess.time("maybe_create_a_macro_crate", || { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 9da806e0779a0..e66ea6f2ca961 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -213,9 +213,8 @@ impl<'tcx> Queries<'tcx> { // Some other attribute. Some(_) => { - tcx.dcx().emit_warning(RustcErrorUnexpectedAnnotation { - span: tcx.def_span(def_id), - }); + tcx.dcx() + .emit_warn(RustcErrorUnexpectedAnnotation { span: tcx.def_span(def_id) }); } } } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 92a6445ed0916..9fd44e46b316e 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -431,7 +431,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Outpu let unnamed_output_types = sess.opts.output_types.values().filter(|a| a.is_none()).count(); let ofile = if unnamed_output_types > 1 { - sess.dcx().emit_warning(errors::MultipleOutputTypesAdaption); + sess.dcx().emit_warn(errors::MultipleOutputTypesAdaption); None } else { if !sess.opts.cg.extra_filename.is_empty() { - sess.dcx().emit_warning(errors::IgnoringExtraFilename); + sess.dcx().emit_warn(errors::IgnoringExtraFilename); } Some(out_file.clone()) }; if sess.io.output_dir != None { - sess.dcx().emit_warning(errors::IgnoringOutDir); + sess.dcx().emit_warn(errors::IgnoringOutDir); } let out_filestem = diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 6dade43a18357..a86fe2db2b2d5 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -29,7 +29,6 @@ use rustc_span::{Span, Symbol}; use rustc_target::abi::{Abi, Size, WrappingRange}; use rustc_target::abi::{Integer, TagEncoding, Variants}; use rustc_target::spec::abi::Abi as SpecAbi; -use rustc_type_ir::DynKind; use std::iter; use std::ops::ControlFlow; @@ -675,7 +674,7 @@ fn lint_wide_pointer<'tcx>( } match ty.kind() { ty::RawPtr(TypeAndMut { mutbl: _, ty }) => (!ty.is_sized(cx.tcx, cx.param_env)) - .then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, DynKind::Dyn)))), + .then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn)))), _ => None, } }; diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index cf3f526400d46..76eb6bfaef721 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -787,7 +787,9 @@ LLVMRustOptimize( for (auto PluginPath: Plugins) { auto Plugin = PassPlugin::Load(PluginPath.str()); if (!Plugin) { - LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str()); + auto Err = Plugin.takeError(); + auto ErrMsg = llvm::toString(std::move(Err)); + LLVMRustSetLastError(ErrMsg.c_str()); return LLVMRustResult::Failure; } Plugin->registerPassBuilderCallbacks(PB); diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 212e831e10614..c5e4dfaf19ee3 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -312,8 +312,9 @@ pub fn struct_lint_level( // create a `DiagnosticBuilder` and continue as we would for warnings. rustc_errors::Level::Expect(expect_id) } - Level::ForceWarn(Some(expect_id)) => rustc_errors::Level::Warning(Some(expect_id)), - Level::Warn | Level::ForceWarn(None) => rustc_errors::Level::Warning(None), + Level::ForceWarn(Some(expect_id)) => rustc_errors::Level::ForceWarning(Some(expect_id)), + Level::ForceWarn(None) => rustc_errors::Level::ForceWarning(None), + Level::Warn => rustc_errors::Level::Warning, Level::Deny | Level::Forbid => rustc_errors::Level::Error, }; let mut err = DiagnosticBuilder::new(sess.dcx(), err_level, ""); @@ -350,22 +351,19 @@ pub fn struct_lint_level( // suppressed the lint due to macros. err.primary_message(msg); + let name = lint.name_lower(); + err.code(DiagnosticId::Lint { name, has_future_breakage }); + // Lint diagnostics that are covered by the expect level will not be emitted outside // the compiler. It is therefore not necessary to add any information for the user. // This will therefore directly call the decorate function which will in turn emit // the `Diagnostic`. if let Level::Expect(_) = level { - let name = lint.name_lower(); - err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn: false }); decorate(&mut err); err.emit(); return; } - let name = lint.name_lower(); - let is_force_warn = matches!(level, Level::ForceWarn(_)); - err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn }); - if let Some(future_incompatible) = future_incompatible { let explanation = match future_incompatible.reason { FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index ec5edceb26997..18e198eb9fcab 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -158,18 +158,36 @@ pub struct Expression { pub rhs: CovTerm, } +#[derive(Clone, Debug)] +#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] +pub enum MappingKind { + /// Associates a normal region of code with a counter/expression/zero. + Code(CovTerm), +} + +impl MappingKind { + /// Iterator over all coverage terms in this mapping kind. + pub fn terms(&self) -> impl Iterator { + let one = |a| std::iter::once(a); + match *self { + Self::Code(term) => one(term), + } + } + + /// Returns a copy of this mapping kind, in which all coverage terms have + /// been replaced with ones returned by the given function. + pub fn map_terms(&self, map_fn: impl Fn(CovTerm) -> CovTerm) -> Self { + match *self { + Self::Code(term) => Self::Code(map_fn(term)), + } + } +} + #[derive(Clone, Debug)] #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct Mapping { + pub kind: MappingKind, pub code_region: CodeRegion, - - /// Indicates whether this mapping uses a counter value, expression value, - /// or zero value. - /// - /// FIXME: When we add support for mapping kinds other than `Code` - /// (e.g. branch regions, expansion regions), replace this with a dedicated - /// mapping-kind enum. - pub term: CovTerm, } /// Stores per-function coverage information attached to a `mir::Body`, diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index a92b85a716f9e..4047891d7697b 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -14,7 +14,6 @@ use either::{Left, Right}; use rustc_ast::Mutability; use rustc_data_structures::intern::Interned; -use rustc_span::DUMMY_SP; use rustc_target::abi::{Align, HasDataLayout, Size}; use super::{ @@ -314,9 +313,7 @@ impl Allocation { /// available to the compiler to do so. pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> { Self::uninit_inner(size, align, || { - ty::tls::with(|tcx| { - tcx.dcx().span_delayed_bug(DUMMY_SP, "exhausted memory during interpretation") - }); + ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation")); InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted).into() }) } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index a1e5d73a0fdb1..1a6b0f4031d38 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -493,8 +493,8 @@ fn write_function_coverage_info( for (id, expression) in expressions.iter_enumerated() { writeln!(w, "{INDENT}coverage {id:?} => {expression:?};")?; } - for coverage::Mapping { term, code_region } in mappings { - writeln!(w, "{INDENT}coverage {term:?} => {code_region:?};")?; + for coverage::Mapping { kind, code_region } in mappings { + writeln!(w, "{INDENT}coverage {kind:?} => {code_region:?};")?; } writeln!(w)?; diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 414d4c8d94961..a41d4f1ad5897 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -551,7 +551,7 @@ macro_rules! define_feedable { // We have an inconsistency. This can happen if one of the two // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed, and keep the `old` value. - tcx.dcx().span_delayed_bug(DUMMY_SP, format!( + tcx.dcx().delayed_bug(format!( "Trying to feed an already recorded value for query {} key={key:?}:\n\ old value: {old:?}\nnew value: {value:?}", stringify!($name), diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 5cc0ce87c9bd7..25473f52c039e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -284,7 +284,7 @@ impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> { type TargetDataLayoutRef = &'tcx TargetDataLayout; fn delayed_bug(&self, txt: String) { - self.tcx.dcx().span_delayed_bug(DUMMY_SP, txt); + self.tcx.dcx().delayed_bug(txt); } fn current_data_layout(&self) -> Self::TargetDataLayoutRef { diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index d9bcd8d3ae72c..5ca88ec31029c 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -132,7 +132,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { .tcx .dcx() .struct_span_err(self.span, "non-defining opaque type use in defining scope") - .span_label_mv( + .with_span_label( self.span, format!( "lifetime `{r}` is part of concrete type but not used in \ diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 38bf39bff908d..8cf5fc8013f1d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1225,7 +1225,7 @@ impl<'tcx> AliasTy<'tcx> { /// Whether this alias type is an opaque. pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool { - matches!(self.opt_kind(tcx), Some(ty::AliasKind::Opaque)) + matches!(self.opt_kind(tcx), Some(ty::Opaque)) } /// FIXME: rename `AliasTy` to `AliasTerm` and always handle @@ -2745,7 +2745,7 @@ impl<'tcx> Ty<'tcx> { // Extern types have metadata = (). | ty::Foreign(..) // `dyn*` has no metadata - | ty::Dynamic(_, _, DynKind::DynStar) + | ty::Dynamic(_, _, ty::DynStar) // If returned by `struct_tail_without_normalization` this is a unit struct // without any fields, or not a struct, and therefore is Sized. | ty::Adt(..) @@ -2754,7 +2754,7 @@ impl<'tcx> Ty<'tcx> { | ty::Tuple(..) => (tcx.types.unit, false), ty::Str | ty::Slice(_) => (tcx.types.usize, false), - ty::Dynamic(_, _, DynKind::Dyn) => { + ty::Dynamic(_, _, ty::Dyn) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); (tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false) }, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 7285cdb830e39..372f11a5accf3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -369,7 +369,7 @@ impl<'tcx> TyCtxt<'tcx> { if let Some((old_item_id, _)) = dtor_candidate { self.dcx() .struct_span_err(self.def_span(item_id), "multiple drop impls found") - .span_note_mv(self.def_span(old_item_id), "other impl here") + .with_span_note(self.def_span(old_item_id), "other impl here") .delay_as_bug(); } diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 27d04dbe33146..6a03bf243eb46 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -1,7 +1,7 @@ use crate::dep_graph::dep_kinds; use crate::query::plumbing::CyclePlaceholder; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::Representability; @@ -175,7 +175,7 @@ impl<'tcx, T> Value> for Result> } else { tcx.def_span(def_id) }; - let mut diag = struct_span_err!( + let mut diag = struct_span_code_err!( tcx.sess.dcx(), span, E0733, @@ -309,7 +309,7 @@ pub fn recursive_type_error( } s }; - struct_span_err!( + struct_span_code_err!( tcx.dcx(), err_span, E0072, @@ -318,7 +318,7 @@ pub fn recursive_type_error( items_list, pluralize!("has", cycle_len), ) - .multipart_suggestion_mv( + .with_multipart_suggestion( "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle", suggestion, Applicability::HasPlaceholders, diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index e77e82d9954e8..5721957037e82 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -9,7 +9,6 @@ use rustc_middle::thir::*; use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex, }; -use rustc_span::DUMMY_SP; use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -111,15 +110,15 @@ fn lit_to_mir_constant<'tcx>( let LitToConstInput { lit, ty, neg } = lit_input; let trunc = |n| { let param_ty = ty::ParamEnv::reveal_all().and(ty); - let width = tcx - .layout_of(param_ty) - .map_err(|_| { - LitToConstError::Reported(tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("couldn't compute width of literal: {:?}", lit_input.lit), - )) - })? - .size; + let width = + tcx.layout_of(param_ty) + .map_err(|_| { + LitToConstError::Reported(tcx.dcx().delayed_bug(format!( + "couldn't compute width of literal: {:?}", + lit_input.lit + ))) + })? + .size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); @@ -158,16 +157,16 @@ fn lit_to_mir_constant<'tcx>( } (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg) .ok_or_else(|| { - LitToConstError::Reported(tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("couldn't parse float literal: {:?}", lit_input.lit), - )) + LitToConstError::Reported( + tcx.dcx() + .delayed_bug(format!("couldn't parse float literal: {:?}", lit_input.lit)), + ) })?, (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( - tcx.dcx().span_delayed_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), + tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"), )); } _ => return Err(LitToConstError::TypeError), diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 3a56b03948ec9..8d5e6cd4f4100 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,7 +1,6 @@ use rustc_ast as ast; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; -use rustc_span::DUMMY_SP; use crate::build::parse_float_into_scalar; @@ -13,15 +12,15 @@ pub(crate) fn lit_to_const<'tcx>( let trunc = |n| { let param_ty = ParamEnv::reveal_all().and(ty); - let width = tcx - .layout_of(param_ty) - .map_err(|_| { - LitToConstError::Reported(tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("couldn't compute width of literal: {:?}", lit_input.lit), - )) - })? - .size; + let width = + tcx.layout_of(param_ty) + .map_err(|_| { + LitToConstError::Reported(tcx.dcx().delayed_bug(format!( + "couldn't compute width of literal: {:?}", + lit_input.lit + ))) + })? + .size; trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); @@ -60,20 +59,21 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Float(n, _), ty::Float(fty)) => { - let bits = parse_float_into_scalar(*n, *fty, neg) - .ok_or_else(|| { - LitToConstError::Reported(tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("couldn't parse float literal: {:?}", lit_input.lit), - )) - })? - .assert_int(); + let bits = + parse_float_into_scalar(*n, *fty, neg) + .ok_or_else(|| { + LitToConstError::Reported(tcx.dcx().delayed_bug(format!( + "couldn't parse float literal: {:?}", + lit_input.lit + ))) + })? + .assert_int(); ty::ValTree::from_scalar_int(bits) } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( - tcx.dcx().span_delayed_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), + tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"), )); } _ => return Err(LitToConstError::TypeError), 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 e9da12d118e0c..f6c5e4a5cd6e2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -11,7 +11,9 @@ use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::Mutability; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ + struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; @@ -55,7 +57,7 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err } fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> { - struct_span_err!(sess.dcx(), sp, E0004, "{}", &error_message) + struct_span_code_err!(sess.dcx(), sp, E0004, "{}", &error_message) } #[derive(Debug, Copy, Clone, PartialEq)] @@ -430,7 +432,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { } let scrut_ty = scrut.ty; - let report = analyze_match(&cx, &tarms, scrut_ty); + let report = match analyze_match(&cx, &tarms, scrut_ty) { + Ok(report) => report, + Err(err) => { + self.error = Err(err); + return; + } + }; match source { // Don't report arm reachability of desugared `match $iter.into_iter() { iter => .. }` @@ -544,7 +552,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let cx = self.new_cx(refutability, None, scrut, pat.span); let pat = self.lower_pattern(&cx, pat)?; let arms = [MatchArm { pat, arm_data: self.lint_level, has_guard: false }]; - let report = analyze_match(&cx, &arms, pat.ty().inner()); + let report = analyze_match(&cx, &arms, pat.ty().inner())?; Ok((cx, report)) } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index dcd7014f4fc90..a11d224e8f1b5 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -9,7 +9,7 @@ mod tests; use self::counters::{BcbCounter, CoverageCounters}; use self::graph::{BasicCoverageBlock, CoverageGraph}; -use self::spans::CoverageSpans; +use self::spans::{BcbMapping, BcbMappingKind, CoverageSpans}; use crate::MirPass; @@ -141,22 +141,21 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let file_name = Symbol::intern(&source_file.name.for_codegen(self.tcx.sess).to_string_lossy()); + let term_for_bcb = |bcb| { + coverage_counters + .bcb_counter(bcb) + .expect("all BCBs with spans were given counters") + .as_term() + }; + coverage_spans - .bcbs_with_coverage_spans() - // For each BCB with spans, get a coverage term for its counter. - .map(|(bcb, spans)| { - let term = coverage_counters - .bcb_counter(bcb) - .expect("all BCBs with spans were given counters") - .as_term(); - (term, spans) - }) - // Flatten the spans into individual term/span pairs. - .flat_map(|(term, spans)| spans.iter().map(move |&span| (term, span))) - // Convert each span to a code region, and create the final mapping. - .filter_map(|(term, span)| { + .all_bcb_mappings() + .filter_map(|&BcbMapping { kind: bcb_mapping_kind, span }| { + let kind = match bcb_mapping_kind { + BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)), + }; let code_region = make_code_region(source_map, file_name, span, body_span)?; - Some(Mapping { term, code_region }) + Some(Mapping { kind, code_region }) }) .collect::>() } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 5983189984d91..81f6c8312061b 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,5 +1,5 @@ use rustc_data_structures::graph::WithNumNodes; -use rustc_index::IndexVec; +use rustc_index::bit_set::BitSet; use rustc_middle::mir; use rustc_span::{BytePos, Span, DUMMY_SP}; @@ -8,9 +8,21 @@ use crate::coverage::ExtractedHirInfo; mod from_mir; +#[derive(Clone, Copy, Debug)] +pub(super) enum BcbMappingKind { + /// Associates an ordinary executable code span with its corresponding BCB. + Code(BasicCoverageBlock), +} + +#[derive(Debug)] +pub(super) struct BcbMapping { + pub(super) kind: BcbMappingKind, + pub(super) span: Span, +} + pub(super) struct CoverageSpans { - /// Map from BCBs to their list of coverage spans. - bcb_to_spans: IndexVec>, + bcb_has_mappings: BitSet, + mappings: Vec, } impl CoverageSpans { @@ -23,36 +35,42 @@ impl CoverageSpans { hir_info: &ExtractedHirInfo, basic_coverage_blocks: &CoverageGraph, ) -> Option { + let mut mappings = vec![]; + let coverage_spans = CoverageSpansGenerator::generate_coverage_spans( mir_body, hir_info, basic_coverage_blocks, ); + mappings.extend(coverage_spans.into_iter().map(|CoverageSpan { bcb, span, .. }| { + // Each span produced by the generator represents an ordinary code region. + BcbMapping { kind: BcbMappingKind::Code(bcb), span } + })); - if coverage_spans.is_empty() { + if mappings.is_empty() { return None; } - // Group the coverage spans by BCB, with the BCBs in sorted order. - let mut bcb_to_spans = IndexVec::from_elem_n(Vec::new(), basic_coverage_blocks.num_nodes()); - for CoverageSpan { bcb, span, .. } in coverage_spans { - bcb_to_spans[bcb].push(span); + // Identify which BCBs have one or more mappings. + let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes()); + let mut insert = |bcb| { + bcb_has_mappings.insert(bcb); + }; + for &BcbMapping { kind, span: _ } in &mappings { + match kind { + BcbMappingKind::Code(bcb) => insert(bcb), + } } - Some(Self { bcb_to_spans }) + Some(Self { bcb_has_mappings, mappings }) } pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool { - !self.bcb_to_spans[bcb].is_empty() + self.bcb_has_mappings.contains(bcb) } - pub(super) fn bcbs_with_coverage_spans( - &self, - ) -> impl Iterator { - self.bcb_to_spans.iter_enumerated().filter_map(|(bcb, spans)| { - // Only yield BCBs that have at least one coverage span. - (!spans.is_empty()).then_some((bcb, spans.as_slice())) - }) + pub(super) fn all_bcb_mappings(&self) -> impl Iterator { + self.mappings.iter() } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 08e628408394e..2c40cd4d8f26e 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -1093,7 +1093,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co MonoItemCollectionMode::Eager } else { if mode != "lazy" { - tcx.dcx().emit_warning(UnknownCguCollectionMode { mode }); + tcx.dcx().emit_warn(UnknownCguCollectionMode { mode }); } MonoItemCollectionMode::Lazy diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index a45bc58124027..7db9291921f0e 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -250,7 +250,7 @@ impl<'a> StringReader<'a> { if starts_with_number { let span = self.mk_sp(start, self.pos); self.dcx().struct_err("lifetimes cannot start with a number") - .span_mv(span) + .with_span(span) .stash(span, StashKey::LifetimeIsChar); } let ident = Symbol::intern(lifetime_name); @@ -397,7 +397,7 @@ impl<'a> StringReader<'a> { if !terminated { self.dcx() .struct_span_fatal(self.mk_sp(start, end), "unterminated character literal") - .code_mv(error_code!(E0762)) + .with_code(error_code!(E0762)) .emit() } self.cook_quoted(token::Char, Mode::Char, start, end, 1, 1) // ' ' @@ -409,7 +409,7 @@ impl<'a> StringReader<'a> { self.mk_sp(start + BytePos(1), end), "unterminated byte constant", ) - .code_mv(error_code!(E0763)) + .with_code(error_code!(E0763)) .emit() } self.cook_quoted(token::Byte, Mode::Byte, start, end, 2, 1) // b' ' @@ -421,7 +421,7 @@ impl<'a> StringReader<'a> { self.mk_sp(start, end), "unterminated double quote string", ) - .code_mv(error_code!(E0765)) + .with_code(error_code!(E0765)) .emit() } self.cook_quoted(token::Str, Mode::Str, start, end, 1, 1) // " " @@ -433,7 +433,7 @@ impl<'a> StringReader<'a> { self.mk_sp(start + BytePos(1), end), "unterminated double quote byte string", ) - .code_mv(error_code!(E0766)) + .with_code(error_code!(E0766)) .emit() } self.cook_quoted(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" " @@ -445,7 +445,7 @@ impl<'a> StringReader<'a> { self.mk_sp(start + BytePos(1), end), "unterminated C string", ) - .code_mv(error_code!(E0767)) + .with_code(error_code!(E0767)) .emit() } self.cook_c_string(token::CStr, Mode::CStr, start, end, 2, 1) // c" " diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 775082adbe81e..fbc77f2878081 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -264,14 +264,14 @@ pub(crate) fn emit_unescape_error( } EscapeError::UnskippedWhitespaceWarning => { let (c, char_span) = last_char(); - dcx.emit_warning(UnescapeError::UnskippedWhitespace { + dcx.emit_warn(UnescapeError::UnskippedWhitespace { span: err_span, ch: escaped_char(c), char_span, }); } EscapeError::MultipleSkippedLinesWarning => { - dcx.emit_warning(UnescapeError::MultipleSkippedLinesWarning(err_span)); + dcx.emit_warn(UnescapeError::MultipleSkippedLinesWarning(err_span)); } } } diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index d7604d7cebcab..b93f08a21e311 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -246,8 +246,8 @@ pub fn parse_cfg_attr( match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { Ok(r) => return Some(r), Err(e) => { - e.help_mv(format!("the valid syntax is `{CFG_ATTR_GRAMMAR_HELP}`")) - .note_mv(CFG_ATTR_NOTE_REF) + e.with_help(format!("the valid syntax is `{CFG_ATTR_GRAMMAR_HELP}`")) + .with_note(CFG_ATTR_NOTE_REF) .emit(); } } diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index cec657f7b67ae..02dab95233a3b 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -204,8 +204,11 @@ impl<'a> Parser<'a> { attr_sp, fluent::parse_inner_attr_not_permitted_after_outer_doc_comment, ) - .span_label_mv(attr_sp, fluent::parse_label_attr) - .span_label_mv(prev_doc_comment_span, fluent::parse_label_prev_doc_comment) + .with_span_label(attr_sp, fluent::parse_label_attr) + .with_span_label( + prev_doc_comment_span, + fluent::parse_label_prev_doc_comment, + ) } Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => self .dcx() @@ -213,8 +216,8 @@ impl<'a> Parser<'a> { attr_sp, fluent::parse_inner_attr_not_permitted_after_outer_attr, ) - .span_label_mv(attr_sp, fluent::parse_label_attr) - .span_label_mv(prev_outer_attr_sp, fluent::parse_label_prev_attr), + .with_span_label(attr_sp, fluent::parse_label_attr) + .with_span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr), Some(InnerAttrForbiddenReason::InCodeBlock) | None => { self.dcx().struct_span_err(attr_sp, fluent::parse_inner_attr_not_permitted) } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a9cf26d991c71..720a610fdf518 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2847,8 +2847,8 @@ impl<'a> Parser<'a> { let span = label.ident.span.to(self.prev_token.span); self.dcx() .struct_span_err(span, "block label not supported here") - .span_label_mv(span, "not supported here") - .tool_only_span_suggestion_mv( + .with_span_label(span, "not supported here") + .with_tool_only_span_suggestion( label.ident.span.until(self.token.span), "remove this block label", "", diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index db777266b59d2..8ca02452342b2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1753,7 +1753,7 @@ impl<'a> Parser<'a> { err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>, ) -> L { if let Some(diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) { - diag.span_suggestion_verbose_mv( + diag.with_span_suggestion_verbose( lifetime.span.shrink_to_hi(), "add `'` to close the char literal", "'", @@ -1762,7 +1762,7 @@ impl<'a> Parser<'a> { .emit(); } else { err(self) - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( lifetime.span.shrink_to_hi(), "add `'` to close the char literal", "'", @@ -2150,7 +2150,7 @@ impl<'a> Parser<'a> { if [sym::i32, sym::u32, sym::isize, sym::usize].contains(&suffix) { // #59553: warn instead of reject out of hand to allow the fix to percolate // through the ecosystem when people fix their macros - self.dcx().emit_warning(errors::InvalidLiteralSuffixOnTupleIndex { + self.dcx().emit_warn(errors::InvalidLiteralSuffixOnTupleIndex { span, suffix, exception: Some(()), diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 66aa8cbcda4ac..48cf04f7790d0 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -145,7 +145,7 @@ impl<'a> Parser<'a> { mistyped_const_ident.span, format!("`const` keyword was mistyped as `{}`", mistyped_const_ident.as_str()), ) - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( mistyped_const_ident.span, "use the `const` keyword", kw::Const.as_str(), diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index fed3c83a81d16..bcff820da7960 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -10,7 +10,7 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::util::case::Case; use rustc_ast::{self as ast}; use rustc_ast_pretty::pprust; -use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; +use rustc_errors::{struct_span_code_err, Applicability, PResult, StashKey}; use rustc_span::edit_distance::edit_distance; use rustc_span::edition::Edition; use rustc_span::source_map; @@ -741,11 +741,11 @@ impl<'a> Parser<'a> { Ok(Some(item)) => items.extend(item), Err(err) => { self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); - err.span_label_mv( + err.with_span_label( open_brace_span, "while parsing this item list starting here", ) - .span_label_mv(self.prev_token.span, "the item list ends here") + .with_span_label(self.prev_token.span, "the item list ends here") .emit(); break; } @@ -759,14 +759,14 @@ impl<'a> Parser<'a> { if let token::DocComment(..) = self.token.kind { if self.look_ahead(1, |tok| tok == &token::CloseDelim(Delimiter::Brace)) { // FIXME: merge with `DocCommentDoesNotDocumentAnything` (E0585) - struct_span_err!( + struct_span_code_err!( self.dcx(), self.token.span, E0584, "found a documentation comment that doesn't document anything", ) - .span_label_mv(self.token.span, "this doc comment doesn't document anything") - .help_mv( + .with_span_label(self.token.span, "this doc comment doesn't document anything") + .with_help( "doc comments must come before what they document, if a comment was \ intended use `//`", ) @@ -1218,7 +1218,7 @@ impl<'a> Parser<'a> { let before_trait = trai.path.span.shrink_to_lo(); let const_up_to_impl = const_span.with_hi(impl_span.lo()); - err.multipart_suggestion_mv( + err.with_multipart_suggestion( "you might have meant to write a const trait impl", vec![(const_up_to_impl, "".to_owned()), (before_trait, "const ".to_owned())], Applicability::MaybeIncorrect, @@ -1457,7 +1457,7 @@ impl<'a> Parser<'a> { if this.token == token::Not { if let Err(err) = this.unexpected::<()>() { - err.note_mv(fluent::parse_macro_expands_to_enum_variant).emit(); + err.with_note(fluent::parse_macro_expands_to_enum_variant).emit(); } this.bump(); @@ -1855,7 +1855,7 @@ impl<'a> Parser<'a> { if eq_typo || semi_typo { self.bump(); // Gracefully handle small typos. - err.span_suggestion_short_mv( + err.with_span_suggestion_short( self.prev_token.span, "field names and their types are separated with `:`", ":", @@ -1935,10 +1935,10 @@ impl<'a> Parser<'a> { lo.to(self.prev_token.span), format!("functions are not allowed in {adt_ty} definitions"), ) - .help_mv( + .with_help( "unlike in C++, Java, and C#, functions are declared in `impl` blocks", ) - .help_mv("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information") + .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information") } Err(err) => { err.cancel(); @@ -1954,7 +1954,9 @@ impl<'a> Parser<'a> { lo.with_hi(ident.span.hi()), format!("structs are not allowed in {adt_ty} definitions"), ) - .help_mv("consider creating a new `struct` definition instead of nesting"), + .with_help( + "consider creating a new `struct` definition instead of nesting", + ), Err(err) => { err.cancel(); self.restore_snapshot(snapshot); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index c13adfb0532d3..ff2fb6271a8df 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -847,7 +847,7 @@ impl<'a> Parser<'a> { pprust::token_to_string(&self.prev_token) ); expect_err - .span_suggestion_verbose_mv( + .with_span_suggestion_verbose( self.prev_token.span.shrink_to_hi().until(self.token.span), msg, " @ ", @@ -863,7 +863,7 @@ impl<'a> Parser<'a> { // Parsed successfully, therefore most probably the code only // misses a separator. expect_err - .span_suggestion_short_mv( + .with_span_suggestion_short( sp, format!("missing `{token_str}`"), token_str, diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 00dc307ab60a0..7918e03750ce3 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -464,7 +464,7 @@ impl<'a> Parser<'a> { self_ .dcx() .struct_span_err(self_.token.span, msg) - .span_label_mv(self_.token.span, format!("expected {expected}")) + .with_span_label(self_.token.span, format!("expected {expected}")) }); PatKind::Lit(self.mk_expr(lo, ExprKind::Lit(lit))) } else { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 5ad17a30980fb..e7cad74b4dd14 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -128,7 +128,7 @@ impl<'a> Parser<'a> { self.prev_token.span, "found single colon before projection in qualified path", ) - .span_suggestion_mv( + .with_span_suggestion( self.prev_token.span, "use double colon", "::", diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 61d72857c36b0..a4fb92c67ac68 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1116,7 +1116,7 @@ impl<'a> Parser<'a> { let before_fn_path = fn_path.span.shrink_to_lo(); self.dcx() .struct_span_err(generic_args_span, "`Fn` traits cannot take lifetime parameters") - .multipart_suggestion_mv( + .with_multipart_suggestion( "consider using a higher-ranked trait bound instead", vec![(generic_args_span, "".to_owned()), (before_fn_path, snippet)], Applicability::MaybeIncorrect, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 724d574349a8e..2fafbd6d97b5d 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -208,7 +208,7 @@ fn emit_malformed_attribute( } else { sess.dcx .struct_span_err(span, error_msg) - .span_suggestions_mv( + .with_span_suggestions( span, if suggestions.len() == 1 { "must be of the form" diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 3e5fb1a6b472e..3e3f2771f5fb1 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -122,7 +122,7 @@ impl<'tcx> CheckConstVisitor<'tcx> { // corresponding feature gate. This encourages nightly users to use feature gates when // possible. None if tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you => { - tcx.dcx().emit_warning(SkippingConstChecks { span }); + tcx.dcx().emit_warn(SkippingConstChecks { span }); return; } diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 0727bad7c5a1d..02f56ecb10b57 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -31,7 +31,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { if !errors.is_empty() { let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); - tcx.dcx().span_delayed_bug(rustc_span::DUMMY_SP, message); + tcx.dcx().delayed_bug(message); } } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index aba08e8b5ca14..92687c705aee6 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -98,7 +98,6 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::DUMMY_SP; use rustc_span::{BytePos, Span}; use std::io; @@ -560,7 +559,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match self.successors[ln] { Some(successor) => self.assigned_on_entry(successor, var), None => { - self.ir.tcx.dcx().span_delayed_bug(DUMMY_SP, "no successor"); + self.ir.tcx.dcx().delayed_bug("no successor"); true } } diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 8ea8dd61ab4be..b52643adcc959 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -24,6 +24,8 @@ use std::fmt; use rustc_index::Idx; #[cfg(feature = "rustc")] use rustc_middle::ty::Ty; +#[cfg(feature = "rustc")] +use rustc_span::ErrorGuaranteed; use crate::constructor::{Constructor, ConstructorSet}; #[cfg(feature = "rustc")] @@ -52,6 +54,8 @@ impl<'a, T: ?Sized> Captures<'a> for T {} pub trait TypeCx: Sized + fmt::Debug { /// The type of a pattern. type Ty: Copy + Clone + fmt::Debug; // FIXME: remove Copy + /// Errors that can abort analysis. + type Error: fmt::Debug; /// The index of an enum variant. type VariantIdx: Clone + Idx; /// A string literal @@ -73,7 +77,7 @@ pub trait TypeCx: Sized + fmt::Debug { /// The set of all the constructors for `ty`. /// /// This must follow the invariants of `ConstructorSet` - fn ctors_for_ty(&self, ty: Self::Ty) -> ConstructorSet; + fn ctors_for_ty(&self, ty: Self::Ty) -> Result, Self::Error>; /// Best-effort `Debug` implementation. fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result; @@ -109,25 +113,25 @@ pub fn analyze_match<'p, 'tcx>( tycx: &RustcMatchCheckCtxt<'p, 'tcx>, arms: &[rustc::MatchArm<'p, 'tcx>], scrut_ty: Ty<'tcx>, -) -> rustc::UsefulnessReport<'p, 'tcx> { +) -> Result, ErrorGuaranteed> { // Arena to store the extra wildcards we construct during analysis. let wildcard_arena = tycx.pattern_arena; let scrut_ty = tycx.reveal_opaque_ty(scrut_ty); let scrut_validity = ValidityConstraint::from_bool(tycx.known_valid_scrutinee); let cx = MatchCtxt { tycx, wildcard_arena }; - let report = compute_match_usefulness(cx, arms, scrut_ty, scrut_validity); + let report = compute_match_usefulness(cx, arms, scrut_ty, scrut_validity)?; let pat_column = PatternColumn::new(arms); // Lint on ranges that overlap on their endpoints, which is likely a mistake. - lint_overlapping_range_endpoints(cx, &pat_column); + lint_overlapping_range_endpoints(cx, &pat_column)?; // Run the non_exhaustive_omitted_patterns lint. Only run on refutable patterns to avoid hitting // `if let`s. Only run if the match is exhaustive otherwise the error is redundant. if tycx.refutable && report.non_exhaustiveness_witnesses.is_empty() { - lint_nonexhaustive_missing_variants(cx, arms, &pat_column, scrut_ty) + lint_nonexhaustive_missing_variants(cx, arms, &pat_column, scrut_ty)?; } - report + Ok(report) } diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index f1237ecf83c68..52c9af850060a 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -4,13 +4,14 @@ use rustc_data_structures::captures::Captures; use rustc_middle::ty; use rustc_session::lint; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use crate::constructor::{IntRange, MaybeInfiniteInt}; use crate::errors::{ NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Overlap, OverlappingRangeEndpoints, Uncovered, }; +use crate::pat::PatOrWild; use crate::rustc::{ Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RevealedTy, RustcMatchCheckCtxt, SplitConstructorSet, WitnessPat, @@ -23,9 +24,9 @@ use crate::rustc::{ /// the depth of patterns, whereas `compute_exhaustiveness_and_usefulness` is worst-case exponential /// (exhaustiveness is NP-complete). The core difference is that we treat sub-columns separately. /// -/// This must not contain an or-pattern. `specialize` takes care to expand them. +/// This must not contain an or-pattern. `expand_and_push` takes care to expand them. /// -/// This is not used in the main algorithm; only in lints. +/// This is not used in the usefulness algorithm; only in lints. #[derive(Debug)] pub(crate) struct PatternColumn<'p, 'tcx> { patterns: Vec<&'p DeconstructedPat<'p, 'tcx>>, @@ -33,28 +34,38 @@ pub(crate) struct PatternColumn<'p, 'tcx> { impl<'p, 'tcx> PatternColumn<'p, 'tcx> { pub(crate) fn new(arms: &[MatchArm<'p, 'tcx>]) -> Self { - let mut patterns = Vec::with_capacity(arms.len()); + let patterns = Vec::with_capacity(arms.len()); + let mut column = PatternColumn { patterns }; for arm in arms { - if arm.pat.is_or_pat() { - patterns.extend(arm.pat.flatten_or_pat()) - } else { - patterns.push(arm.pat) - } + column.expand_and_push(PatOrWild::Pat(arm.pat)); } - Self { patterns } + column } - - fn is_empty(&self) -> bool { - self.patterns.is_empty() + /// Pushes a pattern onto the column, expanding any or-patterns into its subpatterns. + /// Internal method, prefer [`PatternColumn::new`]. + fn expand_and_push(&mut self, pat: PatOrWild<'p, RustcMatchCheckCtxt<'p, 'tcx>>) { + // We flatten or-patterns and skip algorithm-generated wildcards. + if pat.is_or_pat() { + self.patterns.extend( + pat.flatten_or_pat().into_iter().filter_map(|pat_or_wild| pat_or_wild.as_pat()), + ) + } else if let Some(pat) = pat.as_pat() { + self.patterns.push(pat) + } } + fn head_ty(&self) -> Option> { self.patterns.first().map(|pat| pat.ty()) } /// Do constructor splitting on the constructors of the column. - fn analyze_ctors(&self, pcx: &PlaceCtxt<'_, 'p, 'tcx>) -> SplitConstructorSet<'p, 'tcx> { + fn analyze_ctors( + &self, + pcx: &PlaceCtxt<'_, 'p, 'tcx>, + ) -> Result, ErrorGuaranteed> { let column_ctors = self.patterns.iter().map(|p| p.ctor()); - pcx.ctors_for_ty().split(pcx, column_ctors) + let ctors_for_ty = &pcx.ctors_for_ty()?; + Ok(ctors_for_ty.split(pcx, column_ctors)) } fn iter(&self) -> impl Iterator> + Captures<'_> { @@ -83,23 +94,12 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> { (0..arity).map(|_| Self { patterns: Vec::new() }).collect(); let relevant_patterns = self.patterns.iter().filter(|pat| ctor.is_covered_by(pcx, pat.ctor())); - let ctor_sub_tys = pcx.ctor_sub_tys(ctor); for pat in relevant_patterns { - let specialized = pat.specialize(pcx, ctor, ctor_sub_tys); - for (subpat, column) in specialized.iter().zip(&mut specialized_columns) { - if subpat.is_or_pat() { - column.patterns.extend(subpat.flatten_or_pat()) - } else { - column.patterns.push(subpat) - } + let specialized = pat.specialize(ctor, arity); + for (subpat, column) in specialized.into_iter().zip(&mut specialized_columns) { + column.expand_and_push(subpat); } } - - assert!( - !specialized_columns[0].is_empty(), - "ctor {ctor:?} was listed as present but isn't; - there is an inconsistency between `Constructor::is_covered_by` and `ConstructorSet::split`" - ); specialized_columns } } @@ -110,18 +110,18 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> { fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>( cx: MatchCtxt<'a, 'p, 'tcx>, column: &PatternColumn<'p, 'tcx>, -) -> Vec> { +) -> Result>, ErrorGuaranteed> { let Some(ty) = column.head_ty() else { - return Vec::new(); + return Ok(Vec::new()); }; let pcx = &PlaceCtxt::new_dummy(cx, ty); - let set = column.analyze_ctors(pcx); + let set = column.analyze_ctors(pcx)?; if set.present.is_empty() { // We can't consistently handle the case where no constructors are present (since this would // require digging deep through any type in case there's a non_exhaustive enum somewhere), // so for consistency we refuse to handle the top-level case, where we could handle it. - return vec![]; + return Ok(Vec::new()); } let mut witnesses = Vec::new(); @@ -141,7 +141,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>( let wild_pat = WitnessPat::wild_from_ctor(pcx, ctor); for (i, col_i) in specialized_columns.iter().enumerate() { // Compute witnesses for each column. - let wits_for_col_i = collect_nonexhaustive_missing_variants(cx, col_i); + let wits_for_col_i = collect_nonexhaustive_missing_variants(cx, col_i)?; // For each witness, we build a new pattern in the shape of `ctor(_, _, wit, _, _)`, // adding enough wildcards to match `arity`. for wit in wits_for_col_i { @@ -151,7 +151,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>( } } } - witnesses + Ok(witnesses) } pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>( @@ -159,13 +159,13 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>( arms: &[MatchArm<'p, 'tcx>], pat_column: &PatternColumn<'p, 'tcx>, scrut_ty: RevealedTy<'tcx>, -) { +) -> Result<(), ErrorGuaranteed> { let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx; if !matches!( rcx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, rcx.match_lint_level).0, rustc_session::lint::Level::Allow ) { - let witnesses = collect_nonexhaustive_missing_variants(cx, pat_column); + let witnesses = collect_nonexhaustive_missing_variants(cx, pat_column)?; if !witnesses.is_empty() { // Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns` // is not exhaustive enough. @@ -204,6 +204,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>( } } } + Ok(()) } /// Traverse the patterns to warn the user about ranges that overlap on their endpoints. @@ -211,14 +212,14 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>( pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>( cx: MatchCtxt<'a, 'p, 'tcx>, column: &PatternColumn<'p, 'tcx>, -) { +) -> Result<(), ErrorGuaranteed> { let Some(ty) = column.head_ty() else { - return; + return Ok(()); }; let pcx = &PlaceCtxt::new_dummy(cx, ty); let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx; - let set = column.analyze_ctors(pcx); + let set = column.analyze_ctors(pcx)?; if matches!(ty.kind(), ty::Char | ty::Int(_) | ty::Uint(_)) { let emit_lint = |overlap: &IntRange, this_span: Span, overlapped_spans: &[Span]| { @@ -275,8 +276,9 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>( // Recurse into the fields. for ctor in set.present { for col in column.specialize(pcx, &ctor) { - lint_overlapping_range_endpoints(cx, &col); + lint_overlapping_range_endpoints(cx, &col)?; } } } + Ok(()) } diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs index 4438d20a3579b..2f5dc241cb7f5 100644 --- a/compiler/rustc_pattern_analysis/src/pat.rs +++ b/compiler/rustc_pattern_analysis/src/pat.rs @@ -50,14 +50,6 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> { pub(crate) fn is_or_pat(&self) -> bool { matches!(self.ctor, Or) } - /// Expand this (possibly-nested) or-pattern into its alternatives. - pub(crate) fn flatten_or_pat(&self) -> SmallVec<[&Self; 1]> { - if self.is_or_pat() { - self.iter_fields().flat_map(|p| p.flatten_or_pat()).collect() - } else { - smallvec![self] - } - } pub fn ctor(&self) -> &Constructor { &self.ctor @@ -79,17 +71,10 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> { /// `other_ctor` can be different from `self.ctor`, but must be covered by it. pub(crate) fn specialize( &self, - pcx: &PlaceCtxt<'_, 'p, Cx>, other_ctor: &Constructor, - ctor_sub_tys: &[Cx::Ty], - ) -> SmallVec<[&'p DeconstructedPat<'p, Cx>; 2]> { - let wildcard_sub_tys = || { - ctor_sub_tys - .iter() - .map(|ty| DeconstructedPat::wildcard(*ty)) - .map(|pat| pcx.mcx.wildcard_arena.alloc(pat) as &_) - .collect() - }; + ctor_arity: usize, + ) -> SmallVec<[PatOrWild<'p, Cx>; 2]> { + let wildcard_sub_tys = || (0..ctor_arity).map(|_| PatOrWild::Wild).collect(); match (&self.ctor, other_ctor) { // Return a wildcard for each field of `other_ctor`. (Wildcard, _) => wildcard_sub_tys(), @@ -105,14 +90,15 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> { // Fill in the fields from both ends. let new_arity = fields.len(); for i in 0..prefix { - fields[i] = &self.fields[i]; + fields[i] = PatOrWild::Pat(&self.fields[i]); } for i in 0..suffix { - fields[new_arity - 1 - i] = &self.fields[self.fields.len() - 1 - i]; + fields[new_arity - 1 - i] = + PatOrWild::Pat(&self.fields[self.fields.len() - 1 - i]); } fields } - _ => self.fields.iter().collect(), + _ => self.fields.iter().map(PatOrWild::Pat).collect(), } } @@ -153,14 +139,86 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> { } } -/// This is mostly copied from the `Pat` impl. This is best effort and not good enough for a -/// `Display` impl. +/// This is best effort and not good enough for a `Display` impl. impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Cx::debug_pat(f, self) } } +/// Represents either a pattern obtained from user input or a wildcard constructed during the +/// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input. +/// +/// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard. +#[derive(derivative::Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""))] +pub(crate) enum PatOrWild<'p, Cx: TypeCx> { + /// A non-user-provided wildcard, created during specialization. + Wild, + /// A user-provided pattern. + Pat(&'p DeconstructedPat<'p, Cx>), +} + +impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> { + pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> { + match self { + PatOrWild::Wild => None, + PatOrWild::Pat(pat) => Some(pat), + } + } + pub(crate) fn ctor(self) -> &'p Constructor { + match self { + PatOrWild::Wild => &Wildcard, + PatOrWild::Pat(pat) => pat.ctor(), + } + } + + pub(crate) fn is_or_pat(&self) -> bool { + match self { + PatOrWild::Wild => false, + PatOrWild::Pat(pat) => pat.is_or_pat(), + } + } + + /// Expand this (possibly-nested) or-pattern into its alternatives. + pub(crate) fn flatten_or_pat(self) -> SmallVec<[Self; 1]> { + match self { + PatOrWild::Pat(pat) if pat.is_or_pat() => { + pat.iter_fields().flat_map(|p| PatOrWild::Pat(p).flatten_or_pat()).collect() + } + _ => smallvec![self], + } + } + + /// Specialize this pattern with a constructor. + /// `other_ctor` can be different from `self.ctor`, but must be covered by it. + pub(crate) fn specialize( + &self, + other_ctor: &Constructor, + ctor_arity: usize, + ) -> SmallVec<[PatOrWild<'p, Cx>; 2]> { + match self { + PatOrWild::Wild => (0..ctor_arity).map(|_| PatOrWild::Wild).collect(), + PatOrWild::Pat(pat) => pat.specialize(other_ctor, ctor_arity), + } + } + + pub(crate) fn set_useful(&self) { + if let PatOrWild::Pat(pat) = self { + pat.set_useful() + } + } +} + +impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + PatOrWild::Wild => write!(f, "_"), + PatOrWild::Pat(pat) => pat.fmt(f), + } + } +} + /// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics /// purposes. As such they don't use interning and can be cloned. #[derive(derivative::Derivative)] diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index b6f67b7c56fc2..a8d1bece61367 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -12,7 +12,9 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, VariantDef}; +use rustc_span::ErrorGuaranteed; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT}; use smallvec::SmallVec; @@ -302,7 +304,10 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { /// /// See [`crate::constructor`] for considerations of emptiness. #[instrument(level = "debug", skip(self), ret)] - pub fn ctors_for_ty(&self, ty: RevealedTy<'tcx>) -> ConstructorSet<'p, 'tcx> { + pub fn ctors_for_ty( + &self, + ty: RevealedTy<'tcx>, + ) -> Result, ErrorGuaranteed> { let cx = self; let make_uint_range = |start, end| { IntRange::from_range( @@ -311,9 +316,11 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { RangeEnd::Included, ) }; + // Abort on type error. + ty.error_reported()?; // This determines the set of all possible constructors for the type `ty`. For numbers, // arrays and slices we use ranges and variable-length slices when appropriate. - match ty.kind() { + Ok(match ty.kind() { ty::Bool => ConstructorSet::Bool, ty::Char => { // The valid Unicode Scalar Value ranges. @@ -423,7 +430,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { ty::CoroutineWitness(_, _) | ty::Bound(_, _) | ty::Placeholder(_) | ty::Infer(_) => { bug!("Encountered unexpected type in `ConstructorSet::for_ty`: {ty:?}") } - } + }) } pub(crate) fn lower_pat_range_bdy( @@ -944,6 +951,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> { impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> { type Ty = RevealedTy<'tcx>; + type Error = ErrorGuaranteed; type VariantIdx = VariantIdx; type StrLit = Const<'tcx>; type ArmData = HirId; @@ -963,7 +971,10 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> { ) -> &[Self::Ty] { self.ctor_sub_tys(ctor, ty) } - fn ctors_for_ty(&self, ty: Self::Ty) -> crate::constructor::ConstructorSet { + fn ctors_for_ty( + &self, + ty: Self::Ty, + ) -> Result, Self::Error> { self.ctors_for_ty(ty) } diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 16bf709881b6b..b4935d280e66f 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -716,7 +716,7 @@ use smallvec::{smallvec, SmallVec}; use std::fmt; use crate::constructor::{Constructor, ConstructorSet}; -use crate::pat::{DeconstructedPat, WitnessPat}; +use crate::pat::{DeconstructedPat, PatOrWild, WitnessPat}; use crate::{Captures, MatchArm, MatchCtxt, TypeCx}; use self::ValidityConstraint::*; @@ -753,7 +753,7 @@ impl<'a, 'p, Cx: TypeCx> PlaceCtxt<'a, 'p, Cx> { pub(crate) fn ctor_sub_tys(&self, ctor: &Constructor) -> &[Cx::Ty] { self.mcx.tycx.ctor_sub_tys(ctor, self.ty) } - pub(crate) fn ctors_for_ty(&self) -> ConstructorSet { + pub(crate) fn ctors_for_ty(&self) -> Result, Cx::Error> { self.mcx.tycx.ctors_for_ty(self.ty) } } @@ -827,7 +827,7 @@ impl fmt::Display for ValidityConstraint { #[derivative(Clone(bound = ""))] struct PatStack<'p, Cx: TypeCx> { // Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well. - pats: SmallVec<[&'p DeconstructedPat<'p, Cx>; 2]>, + pats: SmallVec<[PatOrWild<'p, Cx>; 2]>, /// Sometimes we know that as far as this row is concerned, the current case is already handled /// by a different, more general, case. When the case is irrelevant for all rows this allows us /// to skip a case entirely. This is purely an optimization. See at the top for details. @@ -836,7 +836,7 @@ struct PatStack<'p, Cx: TypeCx> { impl<'p, Cx: TypeCx> PatStack<'p, Cx> { fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self { - PatStack { pats: smallvec![pat], relevant: true } + PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true } } fn is_empty(&self) -> bool { @@ -847,14 +847,11 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> { self.pats.len() } - fn head_opt(&self) -> Option<&'p DeconstructedPat<'p, Cx>> { - self.pats.first().copied() - } - fn head(&self) -> &'p DeconstructedPat<'p, Cx> { - self.head_opt().unwrap() + fn head(&self) -> PatOrWild<'p, Cx> { + self.pats[0] } - fn iter(&self) -> impl Iterator> + Captures<'_> { + fn iter(&self) -> impl Iterator> + Captures<'_> { self.pats.iter().copied() } @@ -872,14 +869,13 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> { /// Only call if `ctor.is_covered_by(self.head().ctor())` is true. fn pop_head_constructor( &self, - pcx: &PlaceCtxt<'_, 'p, Cx>, ctor: &Constructor, - ctor_sub_tys: &[Cx::Ty], + ctor_arity: usize, ctor_is_relevant: bool, ) -> PatStack<'p, Cx> { // We pop the head pattern and push the new fields extracted from the arguments of // `self.head()`. - let mut new_pats = self.head().specialize(pcx, ctor, ctor_sub_tys); + let mut new_pats = self.head().specialize(ctor, ctor_arity); new_pats.extend_from_slice(&self.pats[1..]); // `ctor` is relevant for this row if it is the actual constructor of this row, or if the // row has a wildcard and `ctor` is relevant for wildcards. @@ -926,11 +922,11 @@ impl<'p, Cx: TypeCx> MatrixRow<'p, Cx> { self.pats.len() } - fn head(&self) -> &'p DeconstructedPat<'p, Cx> { + fn head(&self) -> PatOrWild<'p, Cx> { self.pats.head() } - fn iter(&self) -> impl Iterator> + Captures<'_> { + fn iter(&self) -> impl Iterator> + Captures<'_> { self.pats.iter() } @@ -949,14 +945,13 @@ impl<'p, Cx: TypeCx> MatrixRow<'p, Cx> { /// Only call if `ctor.is_covered_by(self.head().ctor())` is true. fn pop_head_constructor( &self, - pcx: &PlaceCtxt<'_, 'p, Cx>, ctor: &Constructor, - ctor_sub_tys: &[Cx::Ty], + ctor_arity: usize, ctor_is_relevant: bool, parent_row: usize, ) -> MatrixRow<'p, Cx> { MatrixRow { - pats: self.pats.pop_head_constructor(pcx, ctor, ctor_sub_tys, ctor_is_relevant), + pats: self.pats.pop_head_constructor(ctor, ctor_arity, ctor_is_relevant), parent_row, is_under_guard: self.is_under_guard, useful: false, @@ -1054,7 +1049,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> { } /// Iterate over the first pattern of each row. - fn heads(&self) -> impl Iterator> + Clone + Captures<'_> { + fn heads(&self) -> impl Iterator> + Clone + Captures<'_> { self.rows().map(|r| r.head()) } @@ -1066,11 +1061,12 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> { ctor_is_relevant: bool, ) -> Matrix<'p, Cx> { let ctor_sub_tys = pcx.ctor_sub_tys(ctor); + let arity = ctor_sub_tys.len(); let specialized_place_ty = ctor_sub_tys.iter().chain(self.place_ty[1..].iter()).copied().collect(); let ctor_sub_validity = self.place_validity[0].specialize(ctor); let specialized_place_validity = std::iter::repeat(ctor_sub_validity) - .take(ctor.arity(pcx)) + .take(arity) .chain(self.place_validity[1..].iter().copied()) .collect(); let mut matrix = Matrix { @@ -1081,8 +1077,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> { }; for (i, row) in self.rows().enumerate() { if ctor.is_covered_by(pcx, row.head().ctor()) { - let new_row = - row.pop_head_constructor(pcx, ctor, ctor_sub_tys, ctor_is_relevant, i); + let new_row = row.pop_head_constructor(ctor, arity, ctor_is_relevant, i); matrix.expand_and_push(new_row); } } @@ -1341,14 +1336,14 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( mcx: MatchCtxt<'a, 'p, Cx>, matrix: &mut Matrix<'p, Cx>, is_top_level: bool, -) -> WitnessMatrix { +) -> Result, Cx::Error> { debug_assert!(matrix.rows().all(|r| r.len() == matrix.column_count())); if !matrix.wildcard_row_is_relevant && matrix.rows().all(|r| !r.pats.relevant) { // Here we know that nothing will contribute further to exhaustiveness or usefulness. This // is purely an optimization: skipping this check doesn't affect correctness. See the top of // the file for details. - return WitnessMatrix::empty(); + return Ok(WitnessMatrix::empty()); } let Some(ty) = matrix.head_ty() else { @@ -1360,16 +1355,16 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( // When there's an unguarded row, the match is exhaustive and any subsequent row is not // useful. if !row.is_under_guard { - return WitnessMatrix::empty(); + return Ok(WitnessMatrix::empty()); } } // No (unguarded) rows, so the match is not exhaustive. We return a new witness unless // irrelevant. return if matrix.wildcard_row_is_relevant { - WitnessMatrix::unit_witness() + Ok(WitnessMatrix::unit_witness()) } else { // We choose to not report anything here; see at the top for details. - WitnessMatrix::empty() + Ok(WitnessMatrix::empty()) }; }; @@ -1383,7 +1378,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( // Analyze the constructors present in this column. let ctors = matrix.heads().map(|p| p.ctor()); - let ctors_for_ty = pcx.ctors_for_ty(); + let ctors_for_ty = pcx.ctors_for_ty()?; let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. }); // For diagnostics. let split_set = ctors_for_ty.split(pcx, ctors); let all_missing = split_set.present.is_empty(); @@ -1422,7 +1417,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( let mut spec_matrix = matrix.specialize_constructor(pcx, &ctor, ctor_is_relevant); let mut witnesses = ensure_sufficient_stack(|| { compute_exhaustiveness_and_usefulness(mcx, &mut spec_matrix, false) - }); + })?; // Transform witnesses for `spec_matrix` into witnesses for `matrix`. witnesses.apply_constructor(pcx, &missing_ctors, &ctor, report_individual_missing_ctors); @@ -1443,7 +1438,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>( } } - ret + Ok(ret) } /// Indicates whether or not a given arm is useful. @@ -1474,9 +1469,10 @@ pub fn compute_match_usefulness<'p, Cx: TypeCx>( arms: &[MatchArm<'p, Cx>], scrut_ty: Cx::Ty, scrut_validity: ValidityConstraint, -) -> UsefulnessReport<'p, Cx> { +) -> Result, Cx::Error> { let mut matrix = Matrix::new(arms, scrut_ty, scrut_validity); - let non_exhaustiveness_witnesses = compute_exhaustiveness_and_usefulness(cx, &mut matrix, true); + let non_exhaustiveness_witnesses = + compute_exhaustiveness_and_usefulness(cx, &mut matrix, true)?; let non_exhaustiveness_witnesses: Vec<_> = non_exhaustiveness_witnesses.single_column(); let arm_usefulness: Vec<_> = arms @@ -1493,5 +1489,5 @@ pub fn compute_match_usefulness<'p, Cx: TypeCx>( (arm, usefulness) }) .collect(); - UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses } + Ok(UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses }) } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index c5a0cc753a8f1..3bb2cc5634fe8 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -431,17 +431,14 @@ where // We have an inconsistency. This can happen if one of the two // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed. - qcx.dep_context().sess().dcx().span_delayed_bug( - DUMMY_SP, - format!( - "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ + qcx.dep_context().sess().dcx().delayed_bug(format!( + "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ computed={:#?}\nfed={:#?}", - query.dep_kind(), - key, - formatter(&result), - formatter(&cached_result), - ), - ); + query.dep_kind(), + key, + formatter(&result), + formatter(&cached_result), + )); } } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index e176b8b4043c6..9ccfde5e3c621 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -19,7 +19,7 @@ use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use rustc_ast::{Block, Fn, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId}; use rustc_attr as attr; use rustc_data_structures::sync::Lrc; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::{struct_span_code_err, Applicability}; use rustc_expand::expand::AstFragment; use rustc_hir::def::{self, *}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; @@ -818,7 +818,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.r .dcx() .struct_span_err(item.span, "`extern crate self;` requires renaming") - .span_suggestion_mv( + .with_span_suggestion( item.span, "rename the `self` crate to be able to import it", "extern crate self as name;", @@ -999,7 +999,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let msg = format!("`{name}` is already in scope"); let note = "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)"; - self.r.dcx().struct_span_err(span, msg).note_mv(note).emit(); + self.r.dcx().struct_span_err(span, msg).with_note(note).emit(); } } @@ -1010,7 +1010,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { for attr in &item.attrs { if attr.has_name(sym::macro_use) { if self.parent_scope.module.parent.is_some() { - struct_span_err!( + struct_span_code_err!( self.r.dcx(), item.span, E0468, @@ -1024,7 +1024,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } } let ill_formed = |span| { - struct_span_err!(self.r.dcx(), span, E0466, "bad macro import").emit(); + struct_span_code_err!(self.r.dcx(), span, E0466, "bad macro import").emit(); }; match attr.meta() { Some(meta) => match meta.kind { @@ -1095,8 +1095,13 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { allow_shadowing, ); } else { - struct_span_err!(self.r.dcx(), ident.span, E0469, "imported macro not found") - .emit(); + struct_span_code_err!( + self.r.dcx(), + ident.span, + E0469, + "imported macro not found" + ) + .emit(); } } } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 3b1f957c89099..0e43a35ce7389 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -20,7 +20,7 @@ // separate step to be able to collapse the adjacent spans that rustfix // will remove // -// - `check_crate` finally emits the diagnostics based on the data generated +// - `check_unused` finally emits the diagnostics based on the data generated // in the last step use crate::imports::ImportKind; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 57f23200e795a..0d744238eeb42 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -6,7 +6,7 @@ use rustc_ast::{MetaItemKind, NestedMetaItem}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - pluralize, report_ambiguity_error, struct_span_err, Applicability, DiagCtxt, Diagnostic, + pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle, }; use rustc_feature::BUILTIN_ATTRIBUTES; @@ -153,7 +153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { BuiltinLintDiagnostics::AmbiguousGlobImports { diag }, ); } else { - let mut err = struct_span_err!(self.dcx(), diag.span, E0659, "{}", &diag.msg); + let mut err = struct_span_code_err!(self.dcx(), diag.span, E0659, "{}", &diag.msg); report_ambiguity_error(&mut err, diag); err.emit(); } @@ -254,15 +254,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let msg = format!("the name `{name}` is defined multiple times"); let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) { - (true, true) => struct_span_err!(self.dcx(), span, E0259, "{}", msg), + (true, true) => struct_span_code_err!(self.dcx(), span, E0259, "{}", msg), (true, _) | (_, true) => match new_binding.is_import() && old_binding.is_import() { - true => struct_span_err!(self.dcx(), span, E0254, "{}", msg), - false => struct_span_err!(self.dcx(), span, E0260, "{}", msg), + true => struct_span_code_err!(self.dcx(), span, E0254, "{}", msg), + false => struct_span_code_err!(self.dcx(), span, E0260, "{}", msg), }, _ => match (old_binding.is_import_user_facing(), new_binding.is_import_user_facing()) { - (false, false) => struct_span_err!(self.dcx(), span, E0428, "{}", msg), - (true, true) => struct_span_err!(self.dcx(), span, E0252, "{}", msg), - _ => struct_span_err!(self.dcx(), span, E0255, "{}", msg), + (false, false) => struct_span_code_err!(self.dcx(), span, E0428, "{}", msg), + (true, true) => struct_span_code_err!(self.dcx(), span, E0252, "{}", msg), + _ => struct_span_code_err!(self.dcx(), span, E0255, "{}", msg), }, }; @@ -659,7 +659,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let origin_sp = origin.iter().copied().collect::>(); let msp = MultiSpan::from_spans(target_sp.clone()); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), msp, E0408, @@ -788,7 +788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } ResolutionError::FailedToResolve { last_segment, label, suggestion, module } => { let mut err = - struct_span_err!(self.dcx(), span, E0433, "failed to resolve: {}", &label); + struct_span_code_err!(self.dcx(), span, E0433, "failed to resolve: {}", &label); err.span_label(span, label); if let Some((suggestions, msg, applicability)) = suggestion { @@ -950,9 +950,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "item `{name}` is an associated {kind}, which doesn't match its trait `{trait_path}`", ), ) - .code_mv(code) - .span_label_mv(span, "does not match trait") - .span_label_mv(trait_item_span, "item in trait") + .with_code(code) + .with_span_label(span, "does not match trait") + .with_span_label(trait_item_span, "item in trait") } ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self .dcx() @@ -1702,8 +1702,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Print the primary message. let descr = get_descr(binding); - let mut err = - struct_span_err!(self.dcx(), ident.span, E0603, "{} `{}` is private", descr, ident); + let mut err = struct_span_code_err!( + self.dcx(), + ident.span, + E0603, + "{} `{}` is private", + descr, + ident + ); err.span_label(ident.span, format!("private {descr}")); let mut not_publicly_reexported = false; diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index c5bd7ffa038cd..2ebf4c2056266 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -17,7 +17,7 @@ use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult}; use rustc_ast::NodeId; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; -use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan}; use rustc_hir::def::{self, DefKind, PartialRes}; use rustc_middle::metadata::ModChild; use rustc_middle::metadata::Reexport; @@ -686,7 +686,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .collect::>(); let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),); - let mut diag = struct_span_err!(self.dcx(), span, E0432, "{}", &msg); + let mut diag = struct_span_code_err!(self.dcx(), span, E0432, "{}", &msg); if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() { diag.note(note.clone()); @@ -1371,12 +1371,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { - self.dcx().create_err(CannotGlobImportAllCrates { span: import.span }).emit(); + self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); return; }; if module.is_trait() { - self.dcx().create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit(); + self.dcx().emit_err(ItemsInTraitsAreNotImportable { span: import.span }); return; } else if module == import.parent_scope.module { return; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 059ccaebc8208..4a3c8dfe3d729 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1664,7 +1664,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } else { ("`'_` cannot be used here", "`'_` is a reserved lifetime name") }; - let mut diag = rustc_errors::struct_span_err!( + let mut diag = rustc_errors::struct_span_code_err!( self.r.dcx(), lifetime.ident.span, E0637, @@ -1853,7 +1853,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } | LifetimeRibKind::AnonymousWarn(_) => { let sess = self.r.tcx.sess; - let mut err = rustc_errors::struct_span_err!( + let mut err = rustc_errors::struct_span_code_err!( sess.dcx(), path_span, E0726, @@ -2301,7 +2301,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let report_error = |this: &Self, ns| { if this.should_report_errs() { let what = if ns == TypeNS { "type parameters" } else { "local variables" }; - this.r.dcx().create_err(ImportsCannotReferTo { span: ident.span, what }).emit(); + this.r.dcx().emit_err(ImportsCannotReferTo { span: ident.span, what }); } }; @@ -2594,13 +2594,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } if param.ident.name == kw::UnderscoreLifetime { - rustc_errors::struct_span_err!( + rustc_errors::struct_span_code_err!( self.r.dcx(), param.ident.span, E0637, "`'_` cannot be used here" ) - .span_label_mv(param.ident.span, "`'_` is a reserved lifetime name") + .with_span_label(param.ident.span, "`'_` is a reserved lifetime name") .emit(); // Record lifetime res, so lowering knows there is something fishy. self.record_lifetime_param(param.id, LifetimeRes::Error); @@ -2608,14 +2608,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } if param.ident.name == kw::StaticLifetime { - rustc_errors::struct_span_err!( + rustc_errors::struct_span_code_err!( self.r.dcx(), param.ident.span, E0262, "invalid lifetime parameter name: `{}`", param.ident, ) - .span_label_mv(param.ident.span, "'static is a reserved lifetime name") + .with_span_label(param.ident.span, "'static is a reserved lifetime name") .emit(); // Record lifetime res, so lowering knows there is something fishy. self.record_lifetime_param(param.id, LifetimeRes::Error); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a36d1377ab5fd..2f476ae6cbcc1 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -16,7 +16,7 @@ use rustc_ast::{ use rustc_ast_pretty::pprust::where_bound_predicate_to_string; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, + pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle, }; use rustc_hir as hir; @@ -2603,23 +2603,23 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ) { debug_assert_ne!(lifetime_ref.ident.name, kw::UnderscoreLifetime); let mut err = if let Some(outer) = outer_lifetime_ref { - struct_span_err!( + struct_span_code_err!( self.r.dcx(), lifetime_ref.ident.span, E0401, "can't use generic parameters from outer item", ) - .span_label_mv(lifetime_ref.ident.span, "use of generic parameter from outer item") - .span_label_mv(outer.span, "lifetime parameter from outer item") + .with_span_label(lifetime_ref.ident.span, "use of generic parameter from outer item") + .with_span_label(outer.span, "lifetime parameter from outer item") } else { - struct_span_err!( + struct_span_code_err!( self.r.dcx(), lifetime_ref.ident.span, E0261, "use of undeclared lifetime name `{}`", lifetime_ref.ident ) - .span_label_mv(lifetime_ref.ident.span, "undeclared lifetime") + .with_span_label(lifetime_ref.ident.span, "undeclared lifetime") }; self.suggest_introducing_lifetime( &mut err, @@ -2777,7 +2777,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let num_lifetimes: usize = lifetime_refs.iter().map(|lt| lt.count).sum(); let spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect(); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.r.dcx(), spans, E0106, @@ -3282,15 +3282,15 @@ fn mk_where_bound_predicate( /// Report lifetime/lifetime shadowing as an error. pub(super) fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: Ident) { - struct_span_err!( + struct_span_code_err!( sess.dcx(), shadower.span, E0496, "lifetime name `{}` shadows a lifetime name that is already in scope", orig.name, ) - .span_label_mv(orig.span, "first declared here") - .span_label_mv(shadower.span, format!("lifetime `{}` already in scope", orig.name)) + .with_span_label(orig.span, "first declared here") + .with_span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name)) .emit(); } @@ -3322,7 +3322,7 @@ pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident shadower, format!("label name `{name}` shadows a label name that is already in scope"), ) - .span_label_mv(orig, "first declared here") - .span_label_mv(shadower, format!("label `{name}` already in scope")) + .with_span_label(orig, "first declared here") + .with_span_label(shadower, format!("label `{name}` already in scope")) .emit(); } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index fc55481cb0158..66ecaeb4449fc 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust; use rustc_attr::StabilityLevel; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::{struct_span_code_err, Applicability}; use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; @@ -128,7 +128,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { let msg = format!("{} `{}` was already registered", "tool", ident); tcx.dcx() .struct_span_err(ident.span, msg) - .span_label_mv(old_ident.span, "already registered here") + .with_span_label(old_ident.span, "already registered here") .emit(); } } @@ -137,7 +137,7 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { let span = nested_meta.span(); tcx.dcx() .struct_span_err(span, msg) - .span_label_mv(span, "not an identifier") + .with_span_label(span, "not an identifier") .emit(); } } @@ -578,7 +578,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.dcx() .create_err(err) - .span_label_mv(path.span, format!("not {article} {expected}")) + .with_span_label(path.span, format!("not {article} {expected}")) .emit(); return Ok((self.dummy_ext(kind), Res::Err)); @@ -948,13 +948,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { rule_spans = Vec::new(); } BuiltinMacroState::AlreadySeen(span) => { - struct_span_err!( + struct_span_code_err!( self.dcx(), item.span, E0773, "attempted to define built-in macro more than once" ) - .span_note_mv(span, "previously defined here") + .with_span_note(span, "previously defined here") .emit(); } } diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 8baa5d892a5c2..b672e760feb31 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -19,8 +19,8 @@ impl<'a> IntoDiagnostic<'a> for FeatureGateError { #[track_caller] fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> { DiagnosticBuilder::new(dcx, level, self.explain) - .span_mv(self.span) - .code_mv(error_code!(E0658)) + .with_span(self.span) + .with_code(error_code!(E0658)) } } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 439fa18b7fadc..598178c3c2a59 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -143,11 +143,7 @@ pub fn feature_warn_issue( // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level let lint = UNSTABLE_SYNTAX_PRE_EXPANSION; let future_incompatible = lint.future_incompatible.as_ref().unwrap(); - err.code(DiagnosticId::Lint { - name: lint.name_lower(), - has_future_breakage: false, - is_force_warn: false, - }); + err.code(DiagnosticId::Lint { name: lint.name_lower(), has_future_breakage: false }); err.warn(lint.desc); err.note(format!("for more information, see {}", future_incompatible.reference)); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 720599f609544..210dc9e01452c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -263,7 +263,7 @@ impl Session { if !unleashed_features.is_empty() { let mut must_err = false; // Create a diagnostic pointing at where things got unleashed. - self.dcx().emit_warning(errors::SkippingConstChecks { + self.dcx().emit_warn(errors::SkippingConstChecks { unleashed_features: unleashed_features .iter() .map(|(span, gate)| { @@ -341,10 +341,7 @@ impl Session { if self.dcx().err_count() == old_count { Ok(result) } else { - Err(self.dcx().span_delayed_bug( - rustc_span::DUMMY_SP, - "`self.err_count()` changed but an error was not emitted", - )) + Err(self.dcx().delayed_bug("`self.err_count()` changed but an error was not emitted")) } } @@ -574,7 +571,7 @@ impl Session { // We only call `msg` in case we can actually emit warnings. // Otherwise, this could cause a `good_path_delayed_bug` to // trigger (issue #79546). - self.dcx().emit_warning(errors::OptimisationFuelExhausted { msg: msg() }); + self.dcx().emit_warn(errors::OptimisationFuelExhausted { msg: msg() }); } fuel.out_of_fuel = true; } else if fuel.remaining > 0 { @@ -1129,7 +1126,7 @@ pub fn build_session( match profiler { Ok(profiler) => Some(Arc::new(profiler)), Err(e) => { - dcx.emit_warning(errors::FailedToCreateProfiler { err: e.to_string() }); + dcx.emit_warn(errors::FailedToCreateProfiler { err: e.to_string() }); None } } @@ -1341,7 +1338,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { if sess.opts.unstable_opts.stack_protector != StackProtector::None { if !sess.target.options.supports_stack_protector { - sess.dcx().emit_warning(errors::StackProtectorNotSupportedForTarget { + sess.dcx().emit_warn(errors::StackProtectorNotSupportedForTarget { stack_protector: sess.opts.unstable_opts.stack_protector, target_triple: &sess.opts.target_triple, }); @@ -1447,7 +1444,7 @@ impl EarlyDiagCtxt { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_note(&self, msg: impl Into) { - self.dcx.struct_note(msg).emit() + self.dcx.note(msg) } #[allow(rustc::untranslatable_diagnostic)] @@ -1460,13 +1457,13 @@ impl EarlyDiagCtxt { #[allow(rustc::diagnostic_outside_of_impl)] #[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"] pub fn early_err(&self, msg: impl Into) -> ErrorGuaranteed { - self.dcx.struct_err(msg).emit() + self.dcx.err(msg) } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_fatal(&self, msg: impl Into) -> ! { - self.dcx.struct_fatal(msg).emit() + self.dcx.fatal(msg) } #[allow(rustc::untranslatable_diagnostic)] @@ -1481,7 +1478,7 @@ impl EarlyDiagCtxt { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_warn(&self, msg: impl Into) { - self.dcx.struct_warn(msg).emit() + self.dcx.warn(msg) } pub fn initialize_checked_jobserver(&self) { @@ -1491,7 +1488,7 @@ impl EarlyDiagCtxt { #[allow(rustc::diagnostic_outside_of_impl)] self.dcx .struct_warn(err) - .note_mv("the build environment is likely misconfigured") + .with_note("the build environment is likely misconfigured") .emit() }); } diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 17162d0de25c2..5689e8f3b3d94 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -17,7 +17,7 @@ use stable_mir::ty::{ GenericArgKind, GenericArgs, IndexedVal, IntTy, Movability, Region, RigidTy, Span, TermKind, TraitRef, Ty, UintTy, VariantDef, VariantIdx, }; -use stable_mir::{CrateItem, DefId}; +use stable_mir::{CrateItem, CrateNum, DefId}; use super::RustcInternal; @@ -28,6 +28,13 @@ impl<'tcx> RustcInternal<'tcx> for CrateItem { } } +impl<'tcx> RustcInternal<'tcx> for CrateNum { + type T = rustc_span::def_id::CrateNum; + fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T { + rustc_span::def_id::CrateNum::from_usize(*self) + } +} + impl<'tcx> RustcInternal<'tcx> for DefId { type T = rustc_span::def_id::DefId; fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index f84c466cc440d..fffc454804d29 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -25,8 +25,9 @@ use stable_mir::ty::{ AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, GenericArgs, LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, VariantDef, }; -use stable_mir::{Crate, CrateItem, DefId, Error, Filename, ItemKind, Symbol}; +use stable_mir::{Crate, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol}; use std::cell::RefCell; +use std::iter; use crate::rustc_internal::{internal, RustcInternal}; use crate::rustc_smir::builder::BodyBuilder; @@ -67,10 +68,15 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } fn all_trait_decls(&self) -> stable_mir::TraitDecls { + let mut tables = self.0.borrow_mut(); + tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect() + } + + fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls { let mut tables = self.0.borrow_mut(); tables .tcx - .traits(LOCAL_CRATE) + .traits(crate_num.internal(&mut *tables)) .iter() .map(|trait_def_id| tables.trait_def(*trait_def_id)) .collect() @@ -84,10 +90,20 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + iter::once(LOCAL_CRATE) + .chain(tables.tcx.crates(()).iter().copied()) + .flat_map(|cnum| tcx.trait_impls_in_crate(cnum).iter()) + .map(|impl_def_id| tables.impl_def(*impl_def_id)) + .collect() + } + + fn trait_impls(&self, crate_num: CrateNum) -> stable_mir::ImplTraitDecls { let mut tables = self.0.borrow_mut(); tables .tcx - .trait_impls_in_crate(LOCAL_CRATE) + .trait_impls_in_crate(crate_num.internal(&mut *tables)) .iter() .map(|impl_def_id| tables.impl_def(*impl_def_id)) .collect() diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index f0f1d798d44b4..c0ecbfb991413 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -12,12 +12,11 @@ use crate::rustc_smir::{alloc, Stable, Tables}; impl<'tcx> Stable<'tcx> for ty::AliasKind { type T = stable_mir::ty::AliasKind; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::ty::AliasKind::*; match self { - Projection => stable_mir::ty::AliasKind::Projection, - Inherent => stable_mir::ty::AliasKind::Inherent, - Opaque => stable_mir::ty::AliasKind::Opaque, - Weak => stable_mir::ty::AliasKind::Weak, + ty::Projection => stable_mir::ty::AliasKind::Projection, + ty::Inherent => stable_mir::ty::AliasKind::Inherent, + ty::Opaque => stable_mir::ty::AliasKind::Opaque, + ty::Weak => stable_mir::ty::AliasKind::Weak, } } } @@ -34,10 +33,9 @@ impl<'tcx> Stable<'tcx> for ty::DynKind { type T = stable_mir::ty::DynKind; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::ty::DynKind; match self { - DynKind::Dyn => stable_mir::ty::DynKind::Dyn, - DynKind::DynStar => stable_mir::ty::DynKind::DynStar, + ty::Dyn => stable_mir::ty::DynKind::Dyn, + ty::DynStar => stable_mir::ty::DynKind::DynStar, } } } diff --git a/compiler/rustc_symbol_mangling/src/errors.rs b/compiler/rustc_symbol_mangling/src/errors.rs index 746783ab7e3e2..2d076f7b22546 100644 --- a/compiler/rustc_symbol_mangling/src/errors.rs +++ b/compiler/rustc_symbol_mangling/src/errors.rs @@ -18,7 +18,7 @@ impl IntoDiagnostic<'_, G> for TestOutput { let TestOutput { span, kind, content } = self; #[allow(rustc::untranslatable_diagnostic)] - DiagnosticBuilder::new(dcx, level, format!("{kind}({content})")).span_mv(span) + DiagnosticBuilder::new(dcx, level, format!("{kind}({content})")).with_span(span) } } diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index 626569fb40fc0..c05c996175042 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -2,15 +2,29 @@ //! Doing this via a separate goal is called "deferred alias relation" and part //! of our more general approach to "lazy normalization". //! -//! This goal, e.g. `A alias-relate B`, may be satisfied by one of three branches: -//! * normalizes-to: If `A` is a projection, we can prove the equivalent -//! projection predicate with B as the right-hand side of the projection. -//! This goal is computed in both directions, if both are aliases. -//! * subst-relate: Equate `A` and `B` by their substs, if they're both -//! aliases with the same def-id. -//! * bidirectional-normalizes-to: If `A` and `B` are both projections, and both -//! may apply, then we can compute the "intersection" of both normalizes-to by -//! performing them together. This is used specifically to resolve ambiguities. +//! This is done by first normalizing both sides of the goal, ending up in +//! either a concrete type, rigid projection, opaque, or an infer variable. +//! These are related further according to the rules below: +//! +//! (1.) If we end up with a rigid projection and a rigid projection, then we +//! relate those projections structurally. +//! +//! (2.) If we end up with a rigid projection and an alias, then the opaque will +//! have its hidden type defined to be that rigid projection. +//! +//! (3.) If we end up with an opaque and an opaque, then we assemble two +//! candidates, one defining the LHS to be the hidden type of the RHS, and vice +//! versa. +//! +//! (4.) If we end up with an infer var and an opaque or rigid projection, then +//! we assign the alias to the infer var. +//! +//! (5.) If we end up with an opaque and a rigid (non-projection) type, then we +//! define the hidden type of the opaque to be the rigid type. +//! +//! (6.) Otherwise, if we end with two rigid (non-projection) or infer types, +//! relate them structurally. + use super::{EvalCtxt, GoalSource}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::query::NoSolution; @@ -50,6 +64,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.relate(param_env, lhs, variance, rhs)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else if alias.is_opaque(tcx) { + // FIXME: This doesn't account for variance. self.define_opaque(param_env, alias, rhs) } else { Err(NoSolution) @@ -60,6 +75,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.relate(param_env, lhs, variance, rhs)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else if alias.is_opaque(tcx) { + // FIXME: This doesn't account for variance. self.define_opaque(param_env, alias, lhs) } else { Err(NoSolution) @@ -72,6 +88,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } + // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var. /// Normalize the `term` to equate it later. This does not define opaque types. #[instrument(level = "debug", skip(self, param_env), ret)] fn try_normalize_term( diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 2f3111a2414d5..7c8f885a1f24c 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -22,6 +22,7 @@ use rustc_middle::traits::solve::{ CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, IsNormalizesToHack, QueryResult, Response, }; +use rustc_middle::traits::Reveal; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{ CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate, @@ -316,19 +317,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return Some(ty); }; - // We do no always define opaque types eagerly to allow non-defining uses in the defining scope. - if let (DefineOpaqueTypes::No, ty::AliasKind::Opaque) = (define_opaque_types, kind) { - if let Some(def_id) = alias.def_id.as_local() { - if self - .unify_existing_opaque_tys( - param_env, - OpaqueTypeKey { def_id, args: alias.args }, - self.next_ty_infer(), - ) - .is_empty() - { - return Some(ty); - } + // We do no always define opaque types eagerly to allow non-defining uses + // in the defining scope. However, if we can unify this opaque to an existing + // opaque, then we should attempt to eagerly reveal the opaque, and we fall + // through. + if let DefineOpaqueTypes::No = define_opaque_types + && let Reveal::UserFacing = param_env.reveal() + && let ty::Opaque = kind + && let Some(def_id) = alias.def_id.as_local() + && self.can_define_opaque_ty(def_id) + { + if self + .unify_existing_opaque_tys( + param_env, + OpaqueTypeKey { def_id, args: alias.args }, + self.next_ty_infer(), + ) + .is_empty() + { + return Some(ty); } } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index e119ddeb4c6e4..522c645253a21 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -122,8 +122,8 @@ pub fn is_const_evaluatable<'tcx>( if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span }, "failed to evaluate generic const expression", ) - .note_mv("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") - .span_suggestion_verbose_mv( + .with_note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") + .with_span_suggestion_verbose( rustc_span::DUMMY_SP, "consider enabling this feature", "#![feature(generic_const_exprs)]\n", diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index 90e2c1531b469..864580afe623b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -1,7 +1,7 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::InferCtxt; use crate::traits::{Obligation, ObligationCause, ObligationCtxt}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::Node; use rustc_middle::ty::{self, Ty}; @@ -140,7 +140,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let expected_str = args_str(&expected_args, &found_args); let found_str = args_str(&found_args, &expected_args); - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0593, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index c9e8b30c4c48c..100c9a70aaa2d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -6,7 +6,7 @@ use rustc_ast::AttrKind; use rustc_ast::{Attribute, MetaItem, NestedMetaItem}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, ErrorGuaranteed}; +use rustc_errors::{struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::GenericArgsRef; @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use std::iter; use crate::errors::{ @@ -657,9 +657,7 @@ impl<'tcx> OnUnimplementedDirective { Ok(None) } else { - let reported = tcx - .dcx() - .span_delayed_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); + let reported = tcx.dcx().delayed_bug("of_item: neither meta_item_list nor value_str"); return Err(reported); }; debug!("of_item({:?}) = {:?}", item_def_id, result); @@ -797,7 +795,7 @@ impl<'tcx> OnUnimplementedFormatString { }, ); } else { - result = Err(struct_span_err!( + result = Err(struct_span_code_err!( tcx.dcx(), self.span, E0230, @@ -816,7 +814,7 @@ impl<'tcx> OnUnimplementedFormatString { } // `{:1}` and `{}` are not to be used Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => { - let reported = struct_span_err!( + let reported = struct_span_code_err!( tcx.dcx(), self.span, E0231, 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 4a6ef27e7ba3e..6c0909d285395 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -13,7 +13,7 @@ use hir::def::CtorOf; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, + error_code, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan, Style, SuggestionStyle, }; use rustc_hir as hir; @@ -2145,7 +2145,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::Coroutine(..) => "coroutine", _ => "function", }; - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0631, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index b05895e4b9a3d..47a700805fa5c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -19,7 +19,7 @@ use crate::traits::{ }; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{ - pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, + pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, StashKey, Style, }; use rustc_hir as hir; @@ -228,7 +228,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - self.dcx().span_delayed_bug(DUMMY_SP, "expected fulfillment errors") + self.dcx().delayed_bug("expected fulfillment errors") } /// Reports that an overflow has occurred and halts compilation. We @@ -280,7 +280,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { predicate.print(&mut cx).unwrap(); pred_str = cx.into_buffer(); } - let mut err = struct_span_err!( + let mut err = struct_span_code_err!( self.dcx(), span, E0275, @@ -525,7 +525,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { (err_msg, None) }; - let mut err = struct_span_err!(self.dcx(), span, E0277, "{}", err_msg); + let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); let mut suggested = false; if is_try_conversion { @@ -1236,7 +1236,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span_bug!(span, "const param tys cannot mention other generic parameters"); } ty::Float(_) => { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0741, @@ -1244,7 +1244,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } ty::FnPtr(_) => { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0741, @@ -1252,7 +1252,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } ty::RawPtr(_) => { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0741, @@ -1261,7 +1261,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::Adt(def, _) => { // We should probably see if we're *allowed* to derive `ConstParamTy` on the type... - let mut diag = struct_span_err!( + let mut diag = struct_span_code_err!( self.dcx(), span, E0741, @@ -1293,7 +1293,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { diag } _ => { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0741, @@ -1731,7 +1731,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { cx.into_buffer() })) }); - let mut diag = struct_span_err!(self.dcx(), obligation.cause.span, E0271, "{msg}"); + let mut diag = struct_span_code_err!(self.dcx(), obligation.cause.span, E0271, "{msg}"); let secondary_span = (|| { let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) = @@ -2421,7 +2421,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { true, ) } else { - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0283, @@ -2661,17 +2661,17 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ErrorCode::E0284, true, ) - .note_mv(format!("cannot satisfy `{predicate}`")) + .with_note(format!("cannot satisfy `{predicate}`")) } else { // If we can't find a substitution, just print a generic error - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0284, "type annotations needed: cannot satisfy `{}`", predicate, ) - .span_label_mv(span, format!("cannot satisfy `{predicate}`")) + .with_span_label(span, format!("cannot satisfy `{predicate}`")) } } @@ -2691,28 +2691,28 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err } else { // If we can't find a substitution, just print a generic error - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0284, "type annotations needed: cannot satisfy `{}`", predicate, ) - .span_label_mv(span, format!("cannot satisfy `{predicate}`")) + .with_span_label(span, format!("cannot satisfy `{predicate}`")) } } _ => { if self.dcx().has_errors().is_some() || self.tainted_by_errors().is_some() { return; } - struct_span_err!( + struct_span_code_err!( self.dcx(), span, E0284, "type annotations needed: cannot satisfy `{}`", predicate, ) - .span_label_mv(span, format!("cannot satisfy `{predicate}`")) + .with_span_label(span, format!("cannot satisfy `{predicate}`")) } }; self.note_obligation_cause(&mut err, obligation); @@ -3552,7 +3552,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // // Note that with `feature(generic_const_exprs)` this case should not // be reachable. - .note_mv("this may fail depending on what value the parameter takes") + .with_note("this may fail depending on what value the parameter takes") .emit(); return None; } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index d5f98db2c9307..0b73fefd2da9d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -286,10 +286,8 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> // Rustdoc normalizes possibly not well-formed types, so only // treat this as a bug if we're not in rustdoc. if !tcx.sess.opts.actually_rustdoc { - tcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("unexpected ambiguity: {c_data:?} {result:?}"), - ); + tcx.dcx() + .delayed_bug(format!("unexpected ambiguity: {c_data:?} {result:?}")); } return Err(NoSolution); } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index f4baae2711fb0..d533e69a4fa7f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -6,7 +6,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{TyCtxt, TypeFoldable}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use std::fmt; @@ -88,10 +88,9 @@ where if errors.is_empty() { Ok(value) } else { - Err(infcx.dcx().span_delayed_bug( - DUMMY_SP, - format!("errors selecting obligation during MIR typeck: {errors:?}"), - )) + Err(infcx + .dcx() + .delayed_bug(format!("errors selecting obligation during MIR typeck: {errors:?}"))) } })?; diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index c1145bc30c912..342b12ba49848 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -969,7 +969,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx().def_span(impl_def_id), "multiple drop impls found", ) - .span_note_mv( + .with_span_note( self.tcx().def_span(old_impl_def_id), "other impl here", ) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index db89fba2a893e..b8351463c55c7 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -11,7 +11,6 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::symbol::Symbol; -use rustc_span::DUMMY_SP; use rustc_target::abi::*; use std::fmt::Debug; @@ -91,7 +90,7 @@ fn univariant_uninterned<'tcx>( let dl = cx.data_layout(); let pack = repr.pack; if pack.is_some() && repr.align.is_some() { - cx.tcx.dcx().span_delayed_bug(DUMMY_SP, "struct cannot be packed and aligned"); + cx.tcx.dcx().delayed_bug("struct cannot be packed and aligned"); return Err(cx.tcx.arena.alloc(LayoutError::Unknown(ty))); } @@ -344,10 +343,7 @@ fn layout_of_uncached<'tcx>( ty::Adt(def, args) if def.repr().simd() => { if !def.is_struct() { // Should have yielded E0517 by now. - tcx.dcx().span_delayed_bug( - DUMMY_SP, - "#[repr(simd)] was applied to an ADT that is not a struct", - ); + tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct"); return Err(error(cx, LayoutError::Unknown(ty))); } @@ -374,8 +370,7 @@ fn layout_of_uncached<'tcx>( // (should be caught by typeck) for fi in fields { if fi.ty(tcx, args) != f0_ty { - tcx.dcx().span_delayed_bug( - DUMMY_SP, + tcx.dcx().delayed_bug( "#[repr(simd)] was applied to an ADT with heterogeneous field type", ); return Err(error(cx, LayoutError::Unknown(ty))); diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index f52e506059bd1..fb83dae571423 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -16,8 +16,8 @@ use crate::ty::{ TraitDef, Ty, TyKind, VariantDef, }; use crate::{ - mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Symbol, - TraitDecls, + mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind, + Symbol, TraitDecls, }; /// This trait defines the interface between stable_mir and the Rust compiler. @@ -32,8 +32,10 @@ pub trait Context { /// Check whether the body of a function is available. fn has_body(&self, item: DefId) -> bool; fn all_trait_decls(&self) -> TraitDecls; + fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls; fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl; fn all_trait_impls(&self) -> ImplTraitDecls; + fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls; fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait; fn generics_of(&self, def_id: DefId) -> Generics; fn predicates_of(&self, def_id: DefId) -> GenericPredicates; diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 9194f1e6bdb5e..de5dfcdf207f7 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -31,7 +31,7 @@ pub use crate::error::*; use crate::mir::pretty::function_name; use crate::mir::Body; use crate::mir::Mutability; -use crate::ty::{ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty}; +use crate::ty::{ImplDef, IndexedVal, Span, TraitDef, Ty}; pub mod abi; #[macro_use] @@ -86,6 +86,18 @@ pub struct Crate { pub is_local: bool, } +impl Crate { + /// The list of traits declared in this crate. + pub fn trait_decls(&self) -> TraitDecls { + with(|cx| cx.trait_decls(self.id)) + } + + /// The list of trait implementations in this crate. + pub fn trait_impls(&self) -> ImplTraitDecls { + with(|cx| cx.trait_impls(self.id)) + } +} + #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub enum ItemKind { Fn, @@ -169,18 +181,10 @@ pub fn all_trait_decls() -> TraitDecls { with(|cx| cx.all_trait_decls()) } -pub fn trait_decl(trait_def: &TraitDef) -> TraitDecl { - with(|cx| cx.trait_decl(trait_def)) -} - pub fn all_trait_impls() -> ImplTraitDecls { with(|cx| cx.all_trait_impls()) } -pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { - with(|cx| cx.trait_impl(trait_impl)) -} - /// A type that provides internal information but that can still be used for debug purpose. #[derive(Clone, PartialEq, Eq, Hash)] pub struct Opaque(String); diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 9e6ecbe8315b5..eba2ac57012b9 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -714,9 +714,16 @@ crate_def! { } crate_def! { + /// A trait's definition. pub TraitDef; } +impl TraitDef { + pub fn declaration(trait_def: &TraitDef) -> TraitDecl { + with(|cx| cx.trait_decl(trait_def)) + } +} + crate_def! { pub GenericDef; } @@ -726,9 +733,17 @@ crate_def! { } crate_def! { + /// A trait impl definition. pub ImplDef; } +impl ImplDef { + /// Retrieve information about this implementation. + pub fn trait_impl(&self) -> ImplTrait { + with(|cx| cx.trait_impl(self)) + } +} + crate_def! { pub RegionDef; } diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 1ef876a3163c9..4b5862d98a3ab 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -771,7 +771,11 @@ impl Ipv4Addr { || self.is_loopback() || self.is_link_local() // addresses reserved for future protocols (`192.0.0.0/24`) - ||(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0) + // .9 and .10 are documented as globally reachable so they're excluded + || ( + self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0 + && self.octets()[3] != 9 && self.octets()[3] != 10 + ) || self.is_documentation() || self.is_benchmarking() || self.is_reserved() @@ -1515,8 +1519,12 @@ impl Ipv6Addr { // AS112-v6 (`2001:4:112::/48`) || matches!(self.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) // ORCHIDv2 (`2001:20::/28`) - || matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F) + // Drone Remote ID Protocol Entity Tags (DETs) Prefix (`2001:30::/28`)` + || matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x3F) )) + // 6to4 (`2002::/16`) – it's not explicitly documented as globally reachable, + // IANA says N/A. + || matches!(self.segments(), [0x2002, _, _, _, _, _, _, _]) || self.is_documentation() || self.is_unique_local() || self.is_unicast_link_local()) diff --git a/library/core/tests/net/ip_addr.rs b/library/core/tests/net/ip_addr.rs index 7530fc084874d..7f7802c221a61 100644 --- a/library/core/tests/net/ip_addr.rs +++ b/library/core/tests/net/ip_addr.rs @@ -461,6 +461,10 @@ fn ipv4_properties() { check!("198.18.54.2", benchmarking); check!("198.19.255.255", benchmarking); check!("192.0.0.0"); + check!("192.0.0.8"); + check!("192.0.0.9", global); + check!("192.0.0.10", global); + check!("192.0.0.11"); check!("192.0.0.255"); check!("192.0.0.100"); check!("240.0.0.0", reserved); @@ -480,6 +484,10 @@ fn ipv6_properties() { } macro_rules! check { + ($s:expr, &[$($octet:expr),*]) => { + check!($s, &[$($octet),*], 0); + }; + ($s:expr, &[$($octet:expr),*], $mask:expr) => { assert_eq!($s, ip!($s).to_string()); let octets = &[$($octet),*]; @@ -656,8 +664,8 @@ fn ipv6_properties() { &[0x20, 1, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global ); - - check!("2001:30::", &[0x20, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global); + check!("2001:30::", &[0x20, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global); + check!("2001:40::", &[0x20, 1, 0, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global); check!( "2001:200::", @@ -665,6 +673,8 @@ fn ipv6_properties() { global | unicast_global ); + check!("2002::", &[0x20, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global); + check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local); check!( diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index 0c001d7c258c0..184c406e326cf 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -383,8 +383,6 @@ impl Mutex { /// # Examples /// /// ``` - /// #![feature(mutex_unpoison)] - /// /// use std::sync::{Arc, Mutex}; /// use std::thread; /// @@ -406,7 +404,7 @@ impl Mutex { /// assert_eq!(*x, 1); /// ``` #[inline] - #[unstable(feature = "mutex_unpoison", issue = "96469")] + #[stable(feature = "mutex_unpoison", since = "CURRENT_RUSTC_VERSION")] pub fn clear_poison(&self) { self.poison.clear(); } diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 5d8967bfbe686..23d3dd0707a34 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -387,8 +387,6 @@ impl RwLock { /// # Examples /// /// ``` - /// #![feature(mutex_unpoison)] - /// /// use std::sync::{Arc, RwLock}; /// use std::thread; /// @@ -410,7 +408,7 @@ impl RwLock { /// assert_eq!(*guard, 1); /// ``` #[inline] - #[unstable(feature = "mutex_unpoison", issue = "96469")] + #[stable(feature = "mutex_unpoison", since = "CURRENT_RUSTC_VERSION")] pub fn clear_poison(&self) { self.poison.clear(); } diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index 9a59d80556e0f..dce50ebf29c46 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -112,6 +112,90 @@ fn bar() {} fn baz() {} ``` +### Sorting + +In various cases, the default Rust style specifies to sort things. If not +otherwise specified, such sorting should be "version sorting", which ensures +that (for instance) `x8` comes before `x16` even though the character `1` comes +before the character `8`. (If not otherwise specified, version-sorting is +lexicographical.) + +For the purposes of the Rust style, to compare two strings for version-sorting: + +- Process both strings from beginning to end as two sequences of maximal-length + chunks, where each chunk consists either of a sequence of characters other + than ASCII digits, or a sequence of ASCII digits (a numeric chunk), and + compare corresponding chunks from the strings. +- To compare two numeric chunks, compare them by numeric value, ignoring + leading zeroes. If the two chunks have equal numeric value, but different + numbers of leading digits, and this is the first time this has happened for + these strings, treat the chunks as equal (moving on to the next chunk) but + remember which string had more leading zeroes. +- To compare two chunks if both are not numeric, compare them by Unicode + character lexicographically, except that `_` (underscore) sorts immediately + after ` ` (space) but before any other character. (This treats underscore as + a word separator, as commonly used in identifiers.) + - If the use of version sorting specifies further modifiers, such as sorting + non-lowercase before lowercase, apply those modifiers to the lexicographic + sort in this step. +- If the comparison reaches the end of the string and considers each pair of + chunks equal: + - If one of the numeric comparisons noted the earliest point at which one + string had more leading zeroes than the other, sort the string with more + leading zeroes first. + - Otherwise, the strings are equal. + +Note that there exist various algorithms called "version sorting", which +generally try to solve the same problem, but which differ in various ways (such +as in their handling of numbers with leading zeroes). This algorithm +does not purport to precisely match the behavior of any particular other +algorithm, only to produce a simple and satisfying result for Rust formatting. +In particular, this algorithm aims to produce a satisfying result for a set of +symbols that have the same number of leading zeroes, and an acceptable and +easily understandable result for a set of symbols that has varying numbers of +leading zeroes. + +As an example, version-sorting will sort the following strings in the order +given: +- `_ZYWX` +- `u_zzz` +- `u8` +- `u16` +- `u32` +- `u64` +- `u128` +- `u256` +- `ua` +- `usize` +- `uz` +- `v000` +- `v00` +- `v0` +- `v0s` +- `v00t` +- `v0u` +- `v001` +- `v01` +- `v1` +- `v009` +- `v09` +- `v9` +- `v010` +- `v10` +- `w005s09t` +- `w5s009t` +- `x64` +- `x86` +- `x86_32` +- `x86_64` +- `x86_128` +- `x87` +- `Z_YWX` +- `ZY_WX` +- `ZYW_X` +- `ZYWX` +- `ZYWX_` + ### [Module-level items](items.md) ### [Statements](statements.md) diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md index d3b67ae45825d..d47d04642280f 100644 --- a/src/doc/style-guide/src/cargo.md +++ b/src/doc/style-guide/src/cargo.md @@ -8,11 +8,11 @@ Put a blank line between the last key-value pair in a section and the header of the next section. Do not place a blank line between section headers and the key-value pairs in that section, or between key-value pairs in a section. -Sort key names alphabetically within each section, with the exception of the +Version-sort key names within each section, with the exception of the `[package]` section. Put the `[package]` section at the top of the file; put the `name` and `version` keys in that order at the top of that section, -followed by the remaining keys other than `description` in alphabetical order, -followed by the `description` at the end of that section. +followed by the remaining keys other than `description` in order, followed by +the `description` at the end of that section. Don't use quotes around any standard key names; use bare keys. Only use quoted keys for non-standard keys whose names require them, and avoid introducing such diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index 5c67a185b8ffa..19e62c4867c99 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -37,6 +37,8 @@ history of the style guide. Notable changes in the Rust 2024 style edition include: - Miscellaneous `rustfmt` bugfixes. +- Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). +- Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". ## Rust 2015/2018/2021 style edition diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index b215de6ad28a2..0066a4bacb956 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -9,8 +9,8 @@ an item appears at module level or within another item. alphabetically. `use` statements, and module *declarations* (`mod foo;`, not `mod { ... }`) -must come before other items. Put imports before module declarations. Sort each -alphabetically, except that `self` and `super` must come before any other +must come before other items. Put imports before module declarations. +Version-sort each, except that `self` and `super` must come before any other names. Don't automatically move module declarations annotated with `#[macro_use]`, @@ -467,8 +467,10 @@ foo::{ A *group* of imports is a set of imports on the same or sequential lines. One or more blank lines or other items (e.g., a function) separate groups of imports. -Within a group of imports, imports must be sorted ASCIIbetically (uppercase -before lowercase). Groups of imports must not be merged or re-ordered. +Within a group of imports, imports must be version-sorted, except that +non-lowercase characters (characters that can start an `UpperCamelCase` +identifier) must be sorted before lowercase characters. Groups of imports must +not be merged or re-ordered. E.g., input: @@ -495,10 +497,15 @@ re-ordering. ### Ordering list import -Names in a list import must be sorted ASCIIbetically, but with `self` and -`super` first, and groups and glob imports last. This applies recursively. For -example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g., -`use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`. +Names in a list import must be version-sorted, except that: +- `self` and `super` always come first if present, +- non-lowercase characters (characters that can start an `UpperCamelCase` + identifier) must be sorted before lowercase characters, and +- groups and glob imports always come last if present. + +This applies recursively. For example, `a::*` comes before `b::a` but `a::b` +comes before `a::*`. E.g., `use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, +b::{self, r, s}};`. ### Normalisation diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4441060de98a8..9c0a8634990b3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2995,13 +2995,13 @@ fn clean_use_statement_inner<'tcx>( visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module(); if pub_underscore && let Some(ref inline) = inline_attr { - rustc_errors::struct_span_err!( + rustc_errors::struct_span_code_err!( cx.tcx.dcx(), inline.span(), E0780, "anonymous imports cannot be inlined" ) - .span_label_mv(import.span, "anonymous import") + .with_span_label(import.span, "anonymous import") .emit(); } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 614a64d402011..3f7f9270b2da0 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -421,7 +421,7 @@ impl Options { let paths = match theme::load_css_paths(content) { Ok(p) => p, Err(e) => { - dcx.struct_err(e).emit(); + dcx.err(e); return Err(1); } }; @@ -452,10 +452,10 @@ impl Options { let input = PathBuf::from(if describe_lints { "" // dummy, this won't be used } else if matches.free.is_empty() { - dcx.struct_err("missing file operand").emit(); + dcx.err("missing file operand"); return Err(1); } else if matches.free.len() > 1 { - dcx.struct_err("too many file operands").emit(); + dcx.err("too many file operands"); return Err(1); } else { &matches.free[0] @@ -467,7 +467,7 @@ impl Options { let extern_html_root_urls = match parse_extern_html_roots(matches) { Ok(ex) => ex, Err(err) => { - dcx.struct_err(err).emit(); + dcx.err(err); return Err(1); } }; @@ -534,7 +534,7 @@ impl Options { let output = matches.opt_str("output").map(|s| PathBuf::from(&s)); let output = match (out_dir, output) { (Some(_), Some(_)) => { - dcx.struct_err("cannot use both 'out-dir' and 'output' at once").emit(); + dcx.err("cannot use both 'out-dir' and 'output' at once"); return Err(1); } (Some(out_dir), None) => out_dir, @@ -549,7 +549,7 @@ impl Options { if let Some(ref p) = extension_css { if !p.is_file() { - dcx.struct_err("option --extend-css argument must be a file").emit(); + dcx.err("option --extend-css argument must be a file"); return Err(1); } } @@ -567,7 +567,7 @@ impl Options { let paths = match theme::load_css_paths(content) { Ok(p) => p, Err(e) => { - dcx.struct_err(e).emit(); + dcx.err(e); return Err(1); } }; @@ -577,26 +577,26 @@ impl Options { { if !theme_file.is_file() { dcx.struct_err(format!("invalid argument: \"{theme_s}\"")) - .help_mv("arguments to --theme must be files") + .with_help("arguments to --theme must be files") .emit(); return Err(1); } if theme_file.extension() != Some(OsStr::new("css")) { dcx.struct_err(format!("invalid argument: \"{theme_s}\"")) - .help_mv("arguments to --theme must have a .css extension") + .with_help("arguments to --theme must have a .css extension") .emit(); return Err(1); } let (success, ret) = theme::test_theme_against(&theme_file, &paths, &dcx); if !success { - dcx.struct_err(format!("error loading theme file: \"{theme_s}\"")).emit(); + dcx.err(format!("error loading theme file: \"{theme_s}\"")); return Err(1); } else if !ret.is_empty() { dcx.struct_warn(format!( "theme file \"{theme_s}\" is missing CSS rules from the default theme", )) - .warn_mv("the theme may appear incorrect when loaded") - .help_mv(format!( + .with_warn("the theme may appear incorrect when loaded") + .with_help(format!( "to see what rules are missing, call `rustdoc --check-theme \"{theme_s}\"`", )) .emit(); @@ -626,7 +626,7 @@ impl Options { match matches.opt_str("r").as_deref() { Some("rust") | None => {} Some(s) => { - dcx.struct_err(format!("unknown input format: {s}")).emit(); + dcx.err(format!("unknown input format: {s}")); return Err(1); } } @@ -634,7 +634,7 @@ impl Options { let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s)); if let Some(ref index_page) = index_page { if !index_page.is_file() { - dcx.struct_err("option `--index-page` argument must be a file").emit(); + dcx.err("option `--index-page` argument must be a file"); return Err(1); } } @@ -646,7 +646,7 @@ impl Options { let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) { Ok(types) => types, Err(e) => { - dcx.struct_err(format!("unknown crate type: {e}")).emit(); + dcx.err(format!("unknown crate type: {e}")); return Err(1); } }; @@ -664,7 +664,7 @@ impl Options { out_fmt } Err(e) => { - dcx.struct_err(e).emit(); + dcx.err(e); return Err(1); } }, @@ -809,7 +809,7 @@ fn check_deprecated_options(matches: &getopts::Matches, dcx: &rustc_errors::Diag for &flag in deprecated_flags.iter() { if matches.opt_present(flag) { dcx.struct_warn(format!("the `{flag}` flag is deprecated")) - .note_mv( + .with_note( "see issue #44136 \ for more information", ) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 40ea4346f9333..fa72758c21659 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -495,15 +495,15 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> { .intersperse("::") .collect::() ); - rustc_errors::struct_span_err!( + rustc_errors::struct_span_code_err!( self.tcx.dcx(), path.span, E0433, "failed to resolve: {label}", ) - .span_label_mv(path.span, label) - .note_mv("this error was originally ignored because you are running `rustdoc`") - .note_mv("try running again with `rustc` or `cargo check` and you may get a more detailed error") + .with_span_label(path.span, label) + .with_note("this error was originally ignored because you are running `rustdoc`") + .with_note("try running again with `rustc` or `cargo check` and you may get a more detailed error") .emit(); } // We could have an outer resolution that succeeded, diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 8bc0cdf3a9504..57e82b877bf14 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -96,7 +96,7 @@ pub(crate) fn load_string>( match str::from_utf8(&contents) { Ok(s) => Ok(s.to_string()), Err(_) => { - dcx.struct_err(format!("error reading `{}`: not UTF-8", file_path.display())).emit(); + dcx.err(format!("error reading `{}`: not UTF-8", file_path.display())); Err(LoadStringError::BadUtf8) } } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index aad63f8578ad5..fc6f51e8272ae 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -757,8 +757,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { // Flush pending errors. Rc::get_mut(&mut self.shared).unwrap().fs.close(); - let nb_errors = - self.shared.errors.iter().map(|err| self.tcx().dcx().struct_err(err).emit()).count(); + let nb_errors = self.shared.errors.iter().map(|err| self.tcx().dcx().err(err)).count(); if nb_errors > 0 { Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), "")) } else { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ad1838c53ad19..d962beda4beed 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -676,10 +676,7 @@ type MainResult = Result<(), ErrorGuaranteed>; fn wrap_return(dcx: &rustc_errors::DiagCtxt, res: Result<(), String>) -> MainResult { match res { Ok(()) => dcx.has_errors().map_or(Ok(()), Err), - Err(err) => { - let reported = dcx.struct_err(err).emit(); - Err(reported) - } + Err(err) => Err(dcx.err(err)), } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 176494a386341..b843227d18710 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1228,7 +1228,7 @@ impl LinkCollector<'_, '_> { span, "linking to associated items of raw pointers is experimental", ) - .note_mv("rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does") + .with_note("rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does") .emit(); } diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index 98010b056c9a6..31d32e23f8eb9 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -244,7 +244,7 @@ pub(crate) fn test_theme_against>( { Ok(c) => c, Err(e) => { - dcx.struct_err(e).emit(); + dcx.err(e); return (false, vec![]); } }; diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs index 76f3663f04f27..dae9f09ec00a0 100644 --- a/src/tools/clippy/clippy_config/src/msrvs.rs +++ b/src/tools/clippy/clippy_config/src/msrvs.rs @@ -109,7 +109,7 @@ impl Msrv { if let Some(duplicate) = msrv_attrs.last() { sess.dcx() .struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") - .span_note_mv(msrv_attr.span, "first definition found here") + .with_span_note(msrv_attr.span, "first definition found here") .emit(); } diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 19d38903ade28..ad8619f0d3d96 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -136,7 +136,7 @@ pub fn get_unique_attr<'a>( if let Some(duplicate) = unique_attr { sess.dcx() .struct_span_err(attr.span, format!("`{name}` is defined multiple times")) - .span_note_mv(duplicate.span, "first definition found here") + .with_span_note(duplicate.span, "first definition found here") .emit(); } else { unique_attr = Some(attr); diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index d3d4490f30202..bf3284df5967a 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -455,7 +455,7 @@ pub fn report_msg<'tcx>( let sess = machine.tcx.sess; let level = match diag_level { DiagLevel::Error => Level::Error, - DiagLevel::Warning => Level::Warning(None), + DiagLevel::Warning => Level::Warning, DiagLevel::Note => Level::Note, }; let mut err = DiagnosticBuilder::<()>::new(sess.dcx(), level, title); @@ -499,14 +499,12 @@ pub fn report_msg<'tcx>( err.note(if extra_span { "BACKTRACE (of the first span):" } else { "BACKTRACE:" }); } - let (mut err, handler) = err.into_diagnostic().unwrap(); - // Add backtrace for (idx, frame_info) in stacktrace.iter().enumerate() { 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(handler, frame_info.as_note(machine.tcx)); + err.eager_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); @@ -514,7 +512,7 @@ pub fn report_msg<'tcx>( } } - handler.emit_diagnostic(err); + err.emit(); } impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 2663f16b8e8d8..f4fb5073dfdcd 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -446,7 +446,7 @@ mod tests { Some(ignore_list), ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(span)); + let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); emitter.emit_diagnostic(&non_fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0); assert_eq!(can_reset_errors.load(Ordering::Acquire), true); @@ -470,7 +470,7 @@ mod tests { None, ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(span)); + let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); emitter.emit_diagnostic(&non_fatal_diagnostic); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); @@ -507,8 +507,8 @@ mod tests { ); let bar_span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let foo_span = MultiSpan::from_span(mk_sp(BytePos(21), BytePos(22))); - let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(bar_span)); - let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning(None), Some(foo_span)); + let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span)); + let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span)); let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None); emitter.emit_diagnostic(&bar_diagnostic); emitter.emit_diagnostic(&foo_diagnostic); diff --git a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff index 1ef6b69ef5b0c..dec99ff4601a0 100644 --- a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff +++ b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff @@ -4,7 +4,7 @@ fn bar() -> bool { let mut _0: bool; -+ coverage Counter(0) => /the/src/instrument_coverage.rs:21:1 - 23:2; ++ coverage Code(Counter(0)) => /the/src/instrument_coverage.rs:21:1 - 23:2; + bb0: { + Coverage::CounterIncrement(0); diff --git a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 14b4833a515b6..368088d12961a 100644 --- a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -9,11 +9,11 @@ + coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Add, rhs: Counter(1) }; + coverage ExpressionId(1) => Expression { lhs: Expression(0), op: Subtract, rhs: Counter(1) }; -+ coverage Counter(0) => /the/src/instrument_coverage.rs:12:1 - 12:11; -+ coverage Expression(0) => /the/src/instrument_coverage.rs:13:5 - 14:17; -+ coverage Expression(1) => /the/src/instrument_coverage.rs:15:13 - 15:18; -+ coverage Expression(1) => /the/src/instrument_coverage.rs:18:1 - 18:2; -+ coverage Counter(1) => /the/src/instrument_coverage.rs:16:10 - 16:11; ++ coverage Code(Counter(0)) => /the/src/instrument_coverage.rs:12:1 - 12:11; ++ coverage Code(Expression(0)) => /the/src/instrument_coverage.rs:13:5 - 14:17; ++ coverage Code(Expression(1)) => /the/src/instrument_coverage.rs:15:13 - 15:18; ++ coverage Code(Counter(1)) => /the/src/instrument_coverage.rs:16:10 - 16:11; ++ coverage Code(Expression(1)) => /the/src/instrument_coverage.rs:18:1 - 18:2; + bb0: { + Coverage::CounterIncrement(0); diff --git a/tests/ui-fulldeps/stable-mir/check_trait_queries.rs b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs new file mode 100644 index 0000000000000..fb1197e4ecc40 --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/check_trait_queries.rs @@ -0,0 +1,125 @@ +// run-pass +//! Test that users are able to retrieve information about trait declarations and implementations. + +// ignore-stage1 +// ignore-cross-compile +// ignore-remote +// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 +// edition: 2021 + +#![feature(rustc_private)] +#![feature(assert_matches)] +#![feature(control_flow_enum)] + +extern crate rustc_middle; +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate stable_mir; + +use rustc_middle::ty::TyCtxt; +use rustc_smir::rustc_internal; +use stable_mir::CrateDef; +use std::collections::HashSet; +use std::io::Write; +use std::ops::ControlFlow; + +const CRATE_NAME: &str = "trait_test"; + +/// This function uses the Stable MIR APIs to get information about the test crate. +fn test_traits() -> ControlFlow<()> { + let local_crate = stable_mir::local_crate(); + let local_traits = local_crate.trait_decls(); + assert_eq!(local_traits.len(), 1, "Expected `Max` trait, but found {:?}", local_traits); + assert_eq!(&local_traits[0].name(), "Max"); + + let local_impls = local_crate.trait_impls(); + let impl_names = local_impls.iter().map(|trait_impl| trait_impl.name()).collect::>(); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ">"); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, " for u64>"); + + let all_traits = stable_mir::all_trait_decls(); + assert!(all_traits.len() > local_traits.len()); + assert!( + local_traits.iter().all(|t| all_traits.contains(t)), + "Local: {local_traits:#?}, All: {all_traits:#?}" + ); + + let all_impls = stable_mir::all_trait_impls(); + assert!(all_impls.len() > local_impls.len()); + assert!( + local_impls.iter().all(|t| all_impls.contains(t)), + "Local: {local_impls:#?}, All: {all_impls:#?}" + ); + ControlFlow::Continue(()) +} + +fn assert_impl(impl_names: &HashSet, target: &str) { + assert!( + impl_names.contains(target), + "Failed to find `{target}`. Implementations available: {impl_names:?}", + ); +} + +/// This test will generate and analyze a dummy crate using the stable mir. +/// For that, it will first write the dummy crate into a file. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. +fn main() { + let path = "trait_queries.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run!(args, test_traits()).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + use std::convert::TryFrom; + + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub struct Positive(u64); + + impl TryFrom for Positive {{ + type Error = (); + fn try_from(val: u64) -> Result {{ + if val > 0 {{ Ok(Positive(val)) }} else {{ Err(()) }} + }} + }} + + impl From for u64 {{ + fn from(val: Positive) -> u64 {{ val.0 }} + }} + + pub trait Max {{ + fn is_max(&self) -> bool; + }} + + impl Max for u64 {{ + fn is_max(&self) -> bool {{ *self == u64::MAX }} + }} + + impl Max for Positive {{ + fn is_max(&self) -> bool {{ self.0.is_max() }} + }} + + "# + )?; + Ok(()) +} diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.rs b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.rs new file mode 100644 index 0000000000000..6cf459eb82e13 --- /dev/null +++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.rs @@ -0,0 +1,13 @@ +fn main() {} + +fn foo() { + #[derive(Copy, Clone)] + struct Foo(NonExistent); + //~^ ERROR cannot find type + //~| ERROR cannot find type + + type U = impl Copy; + //~^ ERROR `impl Trait` in type aliases is unstable + let foo: U = Foo(()); + let Foo(()) = foo; +} diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr new file mode 100644 index 0000000000000..6d74feb7a9f3f --- /dev/null +++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr @@ -0,0 +1,30 @@ +error[E0412]: cannot find type `NonExistent` in this scope + --> $DIR/issue-119493-type-error-ice.rs:5:16 + | +LL | struct Foo(NonExistent); + | ^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `NonExistent` in this scope + --> $DIR/issue-119493-type-error-ice.rs:5:16 + | +LL | struct Foo(NonExistent); + | ^^^^^^^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct Foo(NonExistent); + | +++++++++++++ + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/issue-119493-type-error-ice.rs:9:14 + | +LL | type U = impl Copy; + | ^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0658. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.rs b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.rs new file mode 100644 index 0000000000000..47333385bc161 --- /dev/null +++ b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.rs @@ -0,0 +1,13 @@ +fn main() {} + +fn foo() { + #[derive(Copy, Clone)] + struct Foo([u8; S]); + //~^ ERROR cannot find value `S` + //~| ERROR cannot find value `S` + + type U = impl Copy; + //~^ ERROR `impl Trait` in type aliases is unstable + let foo: U = Foo(()); + let Foo(()) = foo; +} diff --git a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr new file mode 100644 index 0000000000000..93ef05decd26f --- /dev/null +++ b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr @@ -0,0 +1,35 @@ +error[E0425]: cannot find value `S` in this scope + --> $DIR/issue-119778-type-error-ice.rs:5:21 + | +LL | struct Foo([u8; S]); + | ^ not found in this scope + | +help: you might be missing a const parameter + | +LL | struct Foo([u8; S]); + | +++++++++++++++++++++ + +error[E0425]: cannot find value `S` in this scope + --> $DIR/issue-119778-type-error-ice.rs:5:21 + | +LL | struct Foo([u8; S]); + | ^ not found in this scope + | +help: you might be missing a const parameter + | +LL | struct Foo([u8; S]); + | +++++++++++++++++++++ + +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/issue-119778-type-error-ice.rs:9:14 + | +LL | type U = impl Copy; + | ^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0425, E0658. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs index 6e2ce76632fdc..093aeb4b27911 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.rs +++ b/tests/ui/type-alias-impl-trait/issue-77179.rs @@ -6,9 +6,7 @@ type Pointer = impl std::ops::Deref; fn test() -> Pointer<_> { //~^ ERROR: the placeholder `_` is not allowed within types - //~| ERROR: non-defining opaque type use in defining scope Box::new(1) - //~^ ERROR expected generic type parameter, found `i32` } fn main() { diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr index c5b7c4178e473..68dd6570d00c0 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.stderr +++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr @@ -7,28 +7,6 @@ LL | fn test() -> Pointer<_> { | | not allowed in type signatures | help: replace with the correct return type: `Pointer` -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-77179.rs:7:14 - | -LL | fn test() -> Pointer<_> { - | ^^^^^^^^^^ argument `i32` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-77179.rs:5:19 - | -LL | type Pointer = impl std::ops::Deref; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0792]: expected generic type parameter, found `i32` - --> $DIR/issue-77179.rs:10:5 - | -LL | type Pointer = impl std::ops::Deref; - | - this generic parameter must be used with a generic type parameter -... -LL | Box::new(1) - | ^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0121, E0792. -For more information about an error, try `rustc --explain E0121`. +For more information about this error, try `rustc --explain E0121`. diff --git a/triagebot.toml b/triagebot.toml index 5406500cec302..aac3a830a7875 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -744,6 +744,12 @@ style-team = [ "@yaahc", ] +project-const-traits = [ + "@compiler-errors", + "@fee1-dead", + "@fmease", + "@oli-obk", +] project-stable-mir = [ "@celinval", "@oli-obk",