diff options
| author | Léo Lanteri Thauvin <leseulartichaut@gmail.com> | 2022-07-28 00:03:16 +0200 |
|---|---|---|
| committer | Wim Looman <git@nemo157.com> | 2023-06-13 15:46:54 +0200 |
| commit | 975152ce30b8c0aa3cb7a3dca0a17c6c20e9db5b (patch) | |
| tree | 86168ff07a14bcb6b7888dee11e77dcab9973068 /compiler/rustc_mir_transform/src | |
| parent | a525c7ddba5997b132efa46515e0ce90c173f480 (diff) | |
| download | rust-975152ce30b8c0aa3cb7a3dca0a17c6c20e9db5b.tar.gz rust-975152ce30b8c0aa3cb7a3dca0a17c6c20e9db5b.zip | |
Add MVP suggestion for `unsafe_op_in_unsafe_fn`
Nemo157 rebase notes: Migrated the changes to the lint into fluent
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/check_unsafety.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/errors.rs | 19 |
2 files changed, 34 insertions, 11 deletions
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 069514d8a3b..fd8e02ebeab 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -527,6 +527,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id); + // Only suggest wrapping the entire function body in an unsafe block once + let mut suggest_unsafe_block = true; for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { let details = errors::RequiresUnsafeDetail { violation: details, span: source_info.span }; @@ -561,12 +563,24 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { op_in_unsafe_fn_allowed, }); } - UnsafetyViolationKind::UnsafeFn => tcx.emit_spanned_lint( - UNSAFE_OP_IN_UNSAFE_FN, - lint_root, - source_info.span, - errors::UnsafeOpInUnsafeFn { details }, - ), + UnsafetyViolationKind::UnsafeFn => { + tcx.emit_spanned_lint( + UNSAFE_OP_IN_UNSAFE_FN, + lint_root, + source_info.span, + errors::UnsafeOpInUnsafeFn { + details, + suggest_unsafe_block: suggest_unsafe_block.then(|| { + let body = tcx.hir().body_owned_by(def_id); + let body_span = tcx.hir().body(body).value.span; + let start = tcx.sess.source_map().start_point(body_span).shrink_to_hi(); + let end = tcx.sess.source_map().end_point(body_span).shrink_to_lo(); + (start, end) + }), + }, + ); + suggest_unsafe_block = false; + } } } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 602e40d5131..b546e34f037 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,5 +1,6 @@ use rustc_errors::{ - DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, IntoDiagnostic, + Applicability, DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, + IntoDiagnostic, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails}; @@ -130,6 +131,7 @@ impl RequiresUnsafeDetail { pub(crate) struct UnsafeOpInUnsafeFn { pub details: RequiresUnsafeDetail, + pub suggest_unsafe_block: Option<(Span, Span)>, } impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { @@ -138,13 +140,20 @@ impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { self, diag: &'b mut DiagnosticBuilder<'a, ()>, ) -> &'b mut DiagnosticBuilder<'a, ()> { - let desc = diag - .handler() - .expect("lint should not yet be emitted") - .eagerly_translate_to_string(self.details.label(), [].into_iter()); + let handler = diag.handler().expect("lint should not yet be emitted"); + let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter()); diag.set_arg("details", desc); diag.span_label(self.details.span, self.details.label()); diag.note(self.details.note()); + + if let Some((start, end)) = self.suggest_unsafe_block { + diag.multipart_suggestion_verbose( + crate::fluent_generated::mir_transform_suggestion, + vec![(start, " unsafe {".into()), (end, "}".into())], + Applicability::MaybeIncorrect, + ); + } + diag } |
