diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/generics.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/mod.rs | 55 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/cast.rs | 77 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/generator_interior.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/intrinsicck.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/method/prelude2021.rs | 112 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/method/probe.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/pat.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/upvar.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check_unused.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/orphan.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/generics_of.rs | 5 |
15 files changed, 219 insertions, 209 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index afac75de2d9..5752b6a356d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -649,9 +649,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].hir_id(), multispan, - |lint| { - lint.build(msg).emit(); - }, + msg, + |lint| lint, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 244018ebbeb..cf65bc19a5c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2015,30 +2015,35 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.check_stability(item.def_id, Some(hir_ref_id), span, None); if let Some(variant_def_id) = variant_resolution { - tcx.struct_span_lint_hir(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| { - let mut err = lint.build("ambiguous associated item"); - let mut could_refer_to = |kind: DefKind, def_id, also| { - let note_msg = format!( - "`{}` could{} refer to the {} defined here", - assoc_ident, - also, - kind.descr(def_id) - ); - err.span_note(tcx.def_span(def_id), ¬e_msg); - }; + tcx.struct_span_lint_hir( + AMBIGUOUS_ASSOCIATED_ITEMS, + hir_ref_id, + span, + "ambiguous associated item", + |lint| { + let mut could_refer_to = |kind: DefKind, def_id, also| { + let note_msg = format!( + "`{}` could{} refer to the {} defined here", + assoc_ident, + also, + kind.descr(def_id) + ); + lint.span_note(tcx.def_span(def_id), ¬e_msg); + }; - could_refer_to(DefKind::Variant, variant_def_id, ""); - could_refer_to(kind, item.def_id, " also"); + could_refer_to(DefKind::Variant, variant_def_id, ""); + could_refer_to(kind, item.def_id, " also"); - err.span_suggestion( - span, - "use fully-qualified syntax", - format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), - Applicability::MachineApplicable, - ); + lint.span_suggestion( + span, + "use fully-qualified syntax", + format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), + Applicability::MachineApplicable, + ); - err.emit(); - }); + lint + }, + ); } Ok((ty, kind, item.def_id)) } @@ -3084,15 +3089,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, + msg, |lint| { - let mut diag = lint.build(msg); - diag.multipart_suggestion_verbose( + lint.multipart_suggestion_verbose( "use `dyn`", sugg, Applicability::MachineApplicable, ); - self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag); - diag.emit(); + self.maybe_lint_blanket_trait_impl(&self_ty, lint); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/cast.rs b/compiler/rustc_hir_analysis/src/check/cast.rs index 81a979865ac..01badc133c9 100644 --- a/compiler/rustc_hir_analysis/src/check/cast.rs +++ b/compiler/rustc_hir_analysis/src/check/cast.rs @@ -33,7 +33,7 @@ use super::FnCtxt; use crate::hir::def_id::DefId; use crate::type_error_struct; use hir::def_id::LOCAL_CRATE; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode}; use rustc_middle::mir::Mutability; @@ -754,19 +754,25 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else { ("", lint::builtin::TRIVIAL_CASTS) }; - fcx.tcx.struct_span_lint_hir(lint, self.expr.hir_id, self.span, |err| { - err.build(&format!( - "trivial {}cast: `{}` as `{}`", - adjective, - fcx.ty_to_string(t_expr), - fcx.ty_to_string(t_cast) - )) - .help(&format!( - "cast can be replaced by coercion; this might \ - require {type_asc_or}a temporary variable" - )) - .emit(); - }); + fcx.tcx.struct_span_lint_hir( + lint, + self.expr.hir_id, + self.span, + DelayDm(|| { + format!( + "trivial {}cast: `{}` as `{}`", + adjective, + fcx.ty_to_string(t_expr), + fcx.ty_to_string(t_cast) + ) + }), + |lint| { + lint.help(format!( + "cast can be replaced by coercion; this might \ + require {type_asc_or}a temporary variable" + )) + }, + ); } #[instrument(skip(fcx), level = "debug")] @@ -1074,12 +1080,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::CENUM_IMPL_DROP_CAST, self.expr.hir_id, self.span, - |err| { - err.build(&format!( - "cannot cast enum `{}` into integer `{}` because it implements `Drop`", - self.expr_ty, self.cast_ty - )) - .emit(); + DelayDm(|| format!( + "cannot cast enum `{}` into integer `{}` because it implements `Drop`", + self.expr_ty, self.cast_ty + )), + |lint| { + lint }, ); } @@ -1090,12 +1096,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::LOSSY_PROVENANCE_CASTS, self.expr.hir_id, self.span, - |err| { - let mut err = err.build(&format!( + DelayDm(|| format!( "under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`", self.expr_ty, self.cast_ty - )); - + )), + |lint| { let msg = "use `.addr()` to obtain the address of a pointer"; let expr_prec = self.expr.precedence().order(); @@ -1114,9 +1119,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { (cast_span, format!(").addr(){scalar_cast}")), ]; - err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); + lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); } else { - err.span_suggestion( + lint.span_suggestion( cast_span, msg, format!(".addr(){scalar_cast}"), @@ -1124,12 +1129,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { ); } - err.help( + lint.help( "if you can't comply with strict provenance and need to expose the pointer \ provenance you can use `.expose_addr()` instead" ); - err.emit(); + lint }, ); } @@ -1139,24 +1144,24 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::FUZZY_PROVENANCE_CASTS, self.expr.hir_id, self.span, - |err| { - let mut err = err.build(&format!( - "strict provenance disallows casting integer `{}` to pointer `{}`", - self.expr_ty, self.cast_ty - )); + DelayDm(|| format!( + "strict provenance disallows casting integer `{}` to pointer `{}`", + self.expr_ty, self.cast_ty + )), + |lint| { let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address"; let suggestions = vec![ (self.expr_span.shrink_to_lo(), String::from("(...).with_addr(")), (self.expr_span.shrink_to_hi().to(self.cast_span), String::from(")")), ]; - err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); - err.help( + lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); + lint.help( "if you can't comply with strict provenance and don't have a pointer with \ the correct provenance you can use `std::ptr::from_exposed_addr()` instead" ); - err.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d82ee8f48c5..60a4904373e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -48,9 +48,13 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab .emit(); } None => { - tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.build("use of calling convention not supported on this target").emit(); - }); + tcx.struct_span_lint_hir( + UNSUPPORTED_CALLING_CONVENTIONS, + hir_id, + span, + "use of calling convention not supported on this target", + |lint| lint, + ); } } @@ -510,10 +514,10 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { UNINHABITED_STATIC, tcx.hir().local_def_id_to_hir_id(def_id), span, + "static of uninhabited type", |lint| { - lint.build("static of uninhabited type") + lint .note("uninhabited statics cannot be initialized, and any access would be an immediate error") - .emit(); }, ); } @@ -1434,6 +1438,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()), span, + "zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types", |lint| { let note = if non_exhaustive { "is marked with `#[non_exhaustive]`" @@ -1441,10 +1446,9 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD "contains private fields" }; let field_ty = tcx.def_path_str_with_substs(def_id, substs); - lint.build("zero-sized fields in repr(transparent) cannot contain external non-exhaustive types") + lint .note(format!("this {descr} contains `{field_ty}`, which {note}, \ and makes it not a breaking change to become non-zero-sized in the future.")) - .emit(); }, ) } diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs index 4522678802b..4bd5e9f6ab5 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs @@ -58,17 +58,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); - self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| { - let msg = format!("unreachable {}", kind); - lint.build(&msg) - .span_label(span, &msg) - .span_label( + let msg = format!("unreachable {}", kind); + self.tcx().struct_span_lint_hir( + lint::builtin::UNREACHABLE_CODE, + id, + span, + &msg, + |lint| { + lint.span_label(span, &msg).span_label( orig_span, custom_note .unwrap_or("any code following this expression is unreachable"), ) - .emit(); - }) + }, + ) } } } diff --git a/compiler/rustc_hir_analysis/src/check/generator_interior.rs b/compiler/rustc_hir_analysis/src/check/generator_interior.rs index 254a19368bf..898419b5b23 100644 --- a/compiler/rustc_hir_analysis/src/check/generator_interior.rs +++ b/compiler/rustc_hir_analysis/src/check/generator_interior.rs @@ -6,7 +6,7 @@ use self::drop_ranges::DropRanges; use super::FnCtxt; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_errors::pluralize; +use rustc_errors::{pluralize, DelayDm}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -610,33 +610,33 @@ fn check_must_not_suspend_def( rustc_session::lint::builtin::MUST_NOT_SUSPEND, hir_id, data.source_span, - |lint| { - let msg = format!( + DelayDm(|| { + format!( "{}`{}`{} held across a suspend point, but should not be", data.descr_pre, tcx.def_path_str(def_id), data.descr_post, - ); - let mut err = lint.build(&msg); - + ) + }), + |lint| { // add span pointing to the offending yield/await - err.span_label(data.yield_span, "the value is held across this suspend point"); + lint.span_label(data.yield_span, "the value is held across this suspend point"); // Add optional reason note if let Some(note) = attr.value_str() { // FIXME(guswynn): consider formatting this better - err.span_note(data.source_span, note.as_str()); + lint.span_note(data.source_span, note.as_str()); } // Add some quick suggestions on what to do // FIXME: can `drop` work as a suggestion here as well? - err.span_help( + lint.span_help( data.source_span, "consider using a block (`{ ... }`) \ to shrink the value's scope, ending before the suspend point", ); - err.emit(); + lint }, ); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index d8fe63dbf08..c604c8af8d2 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -328,17 +328,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { lint::builtin::ASM_SUB_REGISTER, expr.hir_id, spans, + "formatting may not be suitable for sub-register argument", |lint| { - let msg = "formatting may not be suitable for sub-register argument"; - let mut err = lint.build(msg); - err.span_label(expr.span, "for this argument"); - err.help(&format!( + lint.span_label(expr.span, "for this argument"); + lint.help(&format!( "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`", )); - err.help(&format!( + lint.help(&format!( "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`", )); - err.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs b/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs index 392695cca68..ca4cdf5a0d0 100644 --- a/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs +++ b/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs @@ -82,14 +82,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, self_expr.hir_id, self_expr.span, + format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name), |lint| { let sp = self_expr.span; - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - let derefs = "*".repeat(pick.autoderefs); let autoref = match pick.autoref_or_ptr_adjustment { @@ -133,7 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - lint.emit(); + lint }, ); } else { @@ -143,6 +139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, call_expr.hir_id, call_expr.span, + format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name), |lint| { let sp = call_expr.span; let trait_name = self.trait_path_or_bare_name( @@ -151,11 +148,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pick.item.container_id(self.tcx), ); - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - let (self_adjusted, precise) = self.adjust_expr(pick, self_expr, sp); if precise { let args = args @@ -202,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - lint.emit(); + lint }, ); } @@ -257,15 +249,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| { - // "type" refers to either a type or, more likely, a trait from which - // the associated function or method is from. - let container_id = pick.item.container_id(self.tcx); - let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); - let trait_generics = self.tcx.generics_of(container_id); - - let trait_name = - if trait_generics.params.len() <= trait_generics.has_self as usize { + self.tcx.struct_span_lint_hir( + RUST_2021_PRELUDE_COLLISIONS, + expr_id, + span, + format!( + "trait-associated function `{}` will become ambiguous in Rust 2021", + method_name.name + ), + |lint| { + // "type" refers to either a type or, more likely, a trait from which + // the associated function or method is from. + let container_id = pick.item.container_id(self.tcx); + let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); + let trait_generics = self.tcx.generics_of(container_id); + + let trait_name = if trait_generics.params.len() <= trait_generics.has_self as usize + { trait_path } else { let counts = trait_generics.own_counts(); @@ -282,44 +282,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }; - let mut lint = lint.build(&format!( - "trait-associated function `{}` will become ambiguous in Rust 2021", - method_name.name - )); - - let mut self_ty_name = self_ty_span - .find_ancestor_inside(span) - .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) - .unwrap_or_else(|| self_ty.to_string()); - - // Get the number of generics the self type has (if an Adt) unless we can determine that - // the user has written the self type with generics already which we (naively) do by looking - // for a "<" in `self_ty_name`. - if !self_ty_name.contains('<') { - if let Adt(def, _) = self_ty.kind() { - let generics = self.tcx.generics_of(def.did()); - if !generics.params.is_empty() { - let counts = generics.own_counts(); - self_ty_name += &format!( - "<{}>", - std::iter::repeat("'_") - .take(counts.lifetimes) - .chain(std::iter::repeat("_").take(counts.types + counts.consts)) - .collect::<Vec<_>>() - .join(", ") - ); + let mut self_ty_name = self_ty_span + .find_ancestor_inside(span) + .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) + .unwrap_or_else(|| self_ty.to_string()); + + // Get the number of generics the self type has (if an Adt) unless we can determine that + // the user has written the self type with generics already which we (naively) do by looking + // for a "<" in `self_ty_name`. + if !self_ty_name.contains('<') { + if let Adt(def, _) = self_ty.kind() { + let generics = self.tcx.generics_of(def.did()); + if !generics.params.is_empty() { + let counts = generics.own_counts(); + self_ty_name += &format!( + "<{}>", + std::iter::repeat("'_") + .take(counts.lifetimes) + .chain( + std::iter::repeat("_").take(counts.types + counts.consts) + ) + .collect::<Vec<_>>() + .join(", ") + ); + } } } - } - lint.span_suggestion( - span, - "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), - Applicability::MachineApplicable, - ); - - lint.emit(); - }); + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); + + lint + }, + ); } fn trait_path_or_bare_name( diff --git a/compiler/rustc_hir_analysis/src/check/method/probe.rs b/compiler/rustc_hir_analysis/src/check/method/probe.rs index 6cd7ced01a3..a761a93dea4 100644 --- a/compiler/rustc_hir_analysis/src/check/method/probe.rs +++ b/compiler/rustc_hir_analysis/src/check/method/probe.rs @@ -409,9 +409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::TYVAR_BEHIND_RAW_POINTER, scope_expr_id, span, - |lint| { - lint.build("type annotations needed").emit(); - }, + "type annotations needed", + |lint| lint, ); } } else { @@ -1358,24 +1357,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { stable_pick: &Pick<'_>, unstable_candidates: &[(Candidate<'tcx>, Symbol)], ) { + let def_kind = stable_pick.item.kind.as_def_kind(); self.tcx.struct_span_lint_hir( lint::builtin::UNSTABLE_NAME_COLLISIONS, self.scope_expr_id, self.span, + format!( + "{} {} with this name may be added to the standard library in the future", + def_kind.article(), + def_kind.descr(stable_pick.item.def_id), + ), |lint| { - let def_kind = stable_pick.item.kind.as_def_kind(); - let mut diag = lint.build(&format!( - "{} {} with this name may be added to the standard library in the future", - def_kind.article(), - def_kind.descr(stable_pick.item.def_id), - )); match (stable_pick.item.kind, stable_pick.item.container) { (ty::AssocKind::Fn, _) => { // FIXME: This should be a `span_suggestion` instead of `help` // However `self.span` only // highlights the method name, so we can't use it. Also consider reusing // the code from `report_method_error()`. - diag.help(&format!( + lint.help(&format!( "call with fully qualified syntax `{}(...)` to keep using the current \ method", self.tcx.def_path_str(stable_pick.item.def_id), @@ -1383,7 +1382,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { let def_id = stable_pick.item.container_id(self.tcx); - diag.span_suggestion( + lint.span_suggestion( self.span, "use the fully qualified path to the associated const", format!( @@ -1399,7 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } if self.tcx.sess.is_nightly_build() { for (candidate, feature) in unstable_candidates { - diag.help(&format!( + lint.help(&format!( "add `#![feature({})]` to the crate attributes to enable `{}`", feature, self.tcx.def_path_str(candidate.item.def_id), @@ -1407,7 +1406,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - diag.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/pat.rs b/compiler/rustc_hir_analysis/src/check/pat.rs index 8906b622b68..178326cfdc4 100644 --- a/compiler/rustc_hir_analysis/src/check/pat.rs +++ b/compiler/rustc_hir_analysis/src/check/pat.rs @@ -1790,10 +1790,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(), ); - self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |build| { - let mut lint = build.build("some fields are not explicitly listed"); + self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| { lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); - lint.help( "ensure that all fields are mentioned explicitly by adding the suggested fields", ); @@ -1801,7 +1799,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "the pattern is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found", ty, )); - lint.emit(); + + lint }); } diff --git a/compiler/rustc_hir_analysis/src/check/upvar.rs b/compiler/rustc_hir_analysis/src/check/upvar.rs index 0b207a6c0be..4f495641691 100644 --- a/compiler/rustc_hir_analysis/src/check/upvar.rs +++ b/compiler/rustc_hir_analysis/src/check/upvar.rs @@ -749,10 +749,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_hir_id, closure_head_span, + reasons.migration_message(), |lint| { - let mut diagnostics_builder = lint.build( - &reasons.migration_message(), - ); for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations { // Labels all the usage of the captured variable and why they are responsible // for migration being needed @@ -760,13 +758,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => { let cause_span = self.tcx.hir().span(*capture_expr_id); - diagnostics_builder.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", + lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", self.tcx.hir().name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span } => { - diagnostics_builder.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", + lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", self.tcx.hir().name(*var_hir_id), )); } @@ -781,13 +779,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { - diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", + lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", self.tcx.hir().name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span: _ } => { - diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", + lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", v = self.tcx.hir().name(*var_hir_id), )); } @@ -800,7 +798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { let var_name = self.tcx.hir().name(*var_hir_id); - diagnostics_builder.span_label(closure_head_span, format!("\ + lint.span_label(closure_head_span, format!("\ in Rust 2018, this closure implements {missing_trait} \ as `{var_name}` implements {missing_trait}, but in Rust 2021, \ this closure will no longer implement {missing_trait} \ @@ -814,7 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>"); + lint.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>"); let diagnostic_msg = format!( "add a dummy let to cause {} to be fully captured", @@ -857,7 +855,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We take the indentation from the next non-empty line. let line2 = lines.find(|line| !line.is_empty()).unwrap_or_default(); let indent = line2.split_once(|c: char| !c.is_whitespace()).unwrap_or_default().0; - diagnostics_builder.span_suggestion( + lint.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(), &diagnostic_msg, format!("\n{indent}{migration_string};"), @@ -868,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // braces, but with more than just the opening // brace on the first line. We put the `let` // directly after the `{`. - diagnostics_builder.span_suggestion( + lint.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(), &diagnostic_msg, format!(" {migration_string};"), @@ -877,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // This is a closure without braces around the body. // We add braces to add the `let` before the body. - diagnostics_builder.multipart_suggestion( + lint.multipart_suggestion( &diagnostic_msg, vec