diff options
Diffstat (limited to 'compiler/rustc_mir_build/src')
6 files changed, 96 insertions, 88 deletions
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 988ebccb633..5e8ce65daf0 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -89,15 +89,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { UNSAFE_OP_IN_UNSAFE_FN, self.hir_context, span, - |lint| { - lint.build(&format!( - "{} is unsafe and requires unsafe block (error E0133)", - description, - )) - .span_label(span, kind.simple_description()) - .note(note) - .emit(); - }, + format!("{} is unsafe and requires unsafe block (error E0133)", description,), + |lint| lint.span_label(span, kind.simple_description()).note(note), ) } SafetyContext::Safe => { @@ -125,14 +118,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { enclosing_unsafe: Option<(Span, &'static str)>, ) { let block_span = self.tcx.sess.source_map().guess_head_span(block_span); - self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, |lint| { - let msg = "unnecessary `unsafe` block"; - let mut db = lint.build(msg); - db.span_label(block_span, msg); + let msg = "unnecessary `unsafe` block"; + self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, msg, |lint| { + lint.span_label(block_span, msg); if let Some((span, kind)) = enclosing_unsafe { - db.span_label(span, format!("because it's nested under this `unsafe` {}", kind)); + lint.span_label(span, format!("because it's nested under this `unsafe` {}", kind)); } - db.emit(); + lint }); } diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 54d549fd66c..b21f30efce8 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -36,16 +36,20 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let sp = tcx.def_span(def_id); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.struct_span_lint_hir(UNCONDITIONAL_RECURSION, hir_id, sp, |lint| { - let mut db = lint.build("function cannot return without recursing"); - db.span_label(sp, "cannot return without recursing"); - // offer some help to the programmer. - for call_span in vis.reachable_recursive_calls { - db.span_label(call_span, "recursive call site"); - } - db.help("a `loop` may express intention better if this is on purpose"); - db.emit(); - }); + tcx.struct_span_lint_hir( + UNCONDITIONAL_RECURSION, + hir_id, + sp, + "function cannot return without recursing", + |lint| { + lint.span_label(sp, "cannot return without recursing"); + // offer some help to the programmer. + for call_span in vis.reachable_recursive_calls { + lint.span_label(call_span, "recursive call site"); + } + lint.help("a `loop` may express intention better if this is on purpose") + }, + ); } } 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 d45b886903b..8fca94119c2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -7,7 +7,7 @@ use super::{PatCtxt, PatternError}; use rustc_arena::TypedArena; use rustc_ast::Mutability; use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, + error_code, pluralize, struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, }; use rustc_hir as hir; @@ -347,19 +347,23 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let span_end = affix.last().unwrap().unwrap().0; let span = span_start.to(span_end); let cnt = affix.len(); - cx.tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, top, span, |lint| { - let s = pluralize!(cnt); - let mut diag = lint.build(&format!("{kind} irrefutable pattern{s} in let chain")); - diag.note(&format!( - "{these} pattern{s} will always match", - these = pluralize!("this", cnt), - )); - diag.help(&format!( - "consider moving {} {suggestion}", - if cnt > 1 { "them" } else { "it" } - )); - diag.emit() - }); + let s = pluralize!(cnt); + cx.tcx.struct_span_lint_hir( + IRREFUTABLE_LET_PATTERNS, + top, + span, + format!("{kind} irrefutable pattern{s} in let chain"), + |lint| { + lint.note(format!( + "{these} pattern{s} will always match", + these = pluralize!("this", cnt), + )) + .help(format!( + "consider moving {} {suggestion}", + if cnt > 1 { "them" } else { "it" } + )) + }, + ); }; if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 { // The chain has a non-zero prefix of irrefutable `let` statements. @@ -561,26 +565,28 @@ fn check_for_bindings_named_same_as_variants( BINDINGS_WITH_VARIANT_NAME, p.hir_id, p.span, + DelayDm(|| format!( + "pattern binding `{}` is named the same as one \ + of the variants of the type `{}`", + ident, cx.tcx.def_path_str(edef.did()) + )), |lint| { let ty_path = cx.tcx.def_path_str(edef.did()); - let mut err = lint.build(&format!( - "pattern binding `{}` is named the same as one \ - of the variants of the type `{}`", - ident, ty_path - )); - err.code(error_code!(E0170)); + lint.code(error_code!(E0170)); + // If this is an irrefutable pattern, and there's > 1 variant, // then we can't actually match on this. Applying the below // suggestion would produce code that breaks on `check_irrefutable`. if rf == Refutable || variant_count == 1 { - err.span_suggestion( + lint.span_suggestion( p.span, "to match on the variant, qualify the path", format!("{}::{}", ty_path, ident), Applicability::MachineApplicable, ); } - err.emit(); + + lint }, ) } @@ -598,14 +604,13 @@ fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool { } fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<Span>) { - tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, |lint| { - let mut err = lint.build("unreachable pattern"); + tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, "unreachable pattern", |lint| { if let Some(catchall) = catchall { // We had a catchall pattern, hint at that. - err.span_label(span, "unreachable pattern"); - err.span_label(catchall, "matches any value"); + lint.span_label(span, "unreachable pattern"); + lint.span_label(catchall, "matches any value"); } - err.emit(); + lint }); } @@ -621,6 +626,11 @@ fn irrefutable_let_patterns( count: usize, span: Span, ) { + let span = match source { + LetSource::LetElse(span) => span, + _ => span, + }; + macro_rules! emit_diag { ( $lint:expr, @@ -630,18 +640,23 @@ fn irrefutable_let_patterns( ) => {{ let s = pluralize!(count); let these = pluralize!("this", count); - let mut diag = $lint.build(&format!("irrefutable {} pattern{s}", $source_name)); - diag.note(&format!("{these} pattern{s} will always match, so the {}", $note_sufix)); - diag.help(concat!("consider ", $help_sufix)); - diag.emit() + tcx.struct_span_lint_hir( + IRREFUTABLE_LET_PATTERNS, + id, + span, + format!("irrefutable {} pattern{s}", $source_name), + |lint| { + lint.note(&format!( + "{these} pattern{s} will always match, so the {}", + $note_sufix + )) + .help(concat!("consider ", $help_sufix)) + }, + ) }}; } - let span = match source { - LetSource::LetElse(span) => span, - _ => span, - }; - tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source { + match source { LetSource::GenericLet => { emit_diag!(lint, "`let`", "`let` is useless", "removing `let`"); } @@ -677,7 +692,7 @@ fn irrefutable_let_patterns( "instead using a `loop { ... }` with a `let` inside it" ); } - }); + }; } fn is_let_irrefutable<'p, 'tcx>( diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index b58685e8958..f2935ca0e3a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,3 +1,4 @@ +use rustc_errors::DelayDm; use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; @@ -205,9 +206,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| { - lint.build(&msg).emit(); - }, + msg, + |lint| lint, ); } else { debug!( @@ -286,9 +286,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, id, span, - |lint| { - lint.build("floating-point types cannot be used in patterns").emit(); - }, + "floating-point types cannot be used in patterns", + |lint| lint, ); } PatKind::Constant { value: cv } @@ -340,15 +339,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, id, span, - |lint| { - let msg = format!( + DelayDm(|| { + format!( "to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", cv.ty(), cv.ty(), - ); - lint.build(&msg).emit(); - }, + ) + }), + |lint| lint, ); } // Since we are behind a reference, we can just bubble the error up so we get a @@ -488,7 +487,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| {lint.build(&msg).emit();}, + msg, + |lint| lint, ); } PatKind::Constant { value: cv } @@ -556,9 +556,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::POINTER_STRUCTURAL_MATCH, id, span, - |lint| { - lint.build(msg).emit(); - }, + msg, + |lint| lint, ); } PatKind::Constant { value: cv } @@ -594,9 +593,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH, id, span, - |lint| { - lint.build(&msg).emit(); - }, + msg, + |lint| lint, ); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 5105f059f9b..91ecfccdb5f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -299,10 +299,10 @@ impl IntRange { lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, hir_id, pcx.span, + "multiple patterns overlap on their endpoints", |lint| { - let mut err = lint.build("multiple patterns overlap on their endpoints"); for (int_range, span) in overlaps { - err.span_label( + lint.span_label( span, &format!( "this range overlaps on `{}`...", @@ -310,9 +310,9 @@ impl IntRange { ), ); } - err.span_label(pcx.span, "... with this range"); - err.note("you likely meant to write mutually exclusive ranges"); - err.emit(); + lint.span_label(pcx.span, "... with this range"); + lint.note("you likely meant to write mutually exclusive ranges"); + lint }, ); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 22b58837148..f1279072844 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -754,9 +754,8 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>( hir_id: HirId, witnesses: Vec<DeconstructedPat<'p, 'tcx>>, ) { - cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, |build| { + cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, "some variants are not matched explicitly", |lint| { let joined_patterns = joined_uncovered_patterns(cx, &witnesses); - let mut lint = build.build("some variants are not matched explicitly"); lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns)); lint.help( "ensure that all variants are matched explicitly by adding the suggested match arms", @@ -765,7 +764,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>( "the matched value is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found", scrut_ty, )); - lint.emit(); + lint }); } |
