about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeSeulArtichaut <leseulartichaut@gmail.com>2020-05-19 00:19:31 +0200
committerLeSeulArtichaut <leseulartichaut@gmail.com>2020-05-27 20:37:57 +0200
commita41f76321a05ce7941d843dc18ea11f7c8a11c6f (patch)
treedea515376304bd07952863073bdbd111bbd072c6
parentb3e012becc6539de9570eee6ce694f07879935d2 (diff)
downloadrust-a41f76321a05ce7941d843dc18ea11f7c8a11c6f.tar.gz
rust-a41f76321a05ce7941d843dc18ea11f7c8a11c6f.zip
Use the lowest of `unsafe_op_in_unsafe_fn` and `safe_borrow_packed` for packed borrows in unsafe fns
-rw-r--r--src/librustc_middle/mir/query.rs4
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs33
2 files changed, 32 insertions, 5 deletions
diff --git a/src/librustc_middle/mir/query.rs b/src/librustc_middle/mir/query.rs
index c63d7215867..99bfb74c243 100644
--- a/src/librustc_middle/mir/query.rs
+++ b/src/librustc_middle/mir/query.rs
@@ -26,6 +26,10 @@ pub enum UnsafetyViolationKind {
     /// Has to be handled as a lint for backwards compatibility.
     /// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
     UnsafeFn,
+    /// Borrow of packed field in an `unsafe fn` but outside an `unsafe` block.
+    /// Has to be handled as a lint for backwards compatibility.
+    /// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
+    UnsafeFnBorrowPacked,
 }
 
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 3cff214f441..177efa2fc0d 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -370,7 +370,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                                 violation.kind = UnsafetyViolationKind::General;
                             }
                         }
-                        UnsafetyViolationKind::UnsafeFn => {
+                        UnsafetyViolationKind::UnsafeFn
+                        | UnsafetyViolationKind::UnsafeFnBorrowPacked => {
                             bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
                         }
                     }
@@ -385,8 +386,11 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                 for violation in violations {
                     let mut violation = *violation;
 
-                    // FIXME(LeSeulArtichaut): what to do with `UnsafetyViolationKind::BorrowPacked`?
-                    violation.kind = UnsafetyViolationKind::UnsafeFn;
+                    if violation.kind == UnsafetyViolationKind::BorrowPacked {
+                        violation.kind = UnsafetyViolationKind::UnsafeFnBorrowPacked;
+                    } else {
+                        violation.kind = UnsafetyViolationKind::UnsafeFn;
+                    }
                     if !self.violations.contains(&violation) {
                         self.violations.push(violation)
                     }
@@ -418,7 +422,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                                     self.violations.push(violation)
                                 }
                             }
-                            UnsafetyViolationKind::UnsafeFn => bug!(
+                            UnsafetyViolationKind::UnsafeFn
+                            | UnsafetyViolationKind::UnsafeFnBorrowPacked => bug!(
                                 "`UnsafetyViolationKind::UnsafeFn` in an `ExplicitUnsafe` context"
                             ),
                         }
@@ -719,13 +724,31 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
                 |lint| {
                     lint.build(&format!(
                         "{} is unsafe and requires unsafe block (error E0133)",
-                        description
+                        description,
                     ))
                     .span_label(source_info.span, &*description.as_str())
                     .note(&details.as_str())
                     .emit();
                 },
             ),
+            UnsafetyViolationKind::UnsafeFnBorrowPacked => {
+                let lint = if tcx.lint_level_at_node(SAFE_PACKED_BORROWS, lint_root).0
+                    <= tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, lint_root).0
+                {
+                    SAFE_PACKED_BORROWS
+                } else {
+                    UNSAFE_OP_IN_UNSAFE_FN
+                };
+                tcx.struct_span_lint_hir(&lint, lint_root, source_info.span, |lint| {
+                    lint.build(&format!(
+                        "{} is unsafe and requires unsafe block (error E0133)",
+                        description,
+                    ))
+                    .span_label(source_info.span, &*description.as_str())
+                    .note(&details.as_str())
+                    .emit();
+                })
+            }
         }
     }