]> git.lizzy.rs Git - rust.git/commitdiff
Also prevent mutation fields directly
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Mon, 5 Nov 2018 12:26:07 +0000 (13:26 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Tue, 4 Dec 2018 09:17:36 +0000 (10:17 +0100)
src/librustc_mir/transform/check_unsafety.rs
src/test/ui/unsafe/ranged_ints2.rs
src/test/ui/unsafe/ranged_ints2.stderr
src/test/ui/unsafe/ranged_ints3.rs
src/test/ui/unsafe/ranged_ints3.stderr
src/test/ui/unsafe/ranged_ints4.rs [new file with mode: 0644]
src/test/ui/unsafe/ranged_ints4.stderr [new file with mode: 0644]

index c7a785ad2c5200ed59d4b0e46d3b1da8d9622159..b124f8b1c0be94d5597b53ba09f46041b5cbea1f 100644 (file)
@@ -187,13 +187,15 @@ fn visit_place(&mut self,
                             kind: UnsafetyViolationKind::BorrowPacked(lint_root)
                         }], &[]);
                     }
-                    let is_freeze = base
-                        .ty(self.mir, self.tcx)
-                        .to_ty(self.tcx)
-                        .is_freeze(self.tcx, self.param_env, self.source_info.span);
-                    if context.is_mutating_use() || !is_freeze {
-                        self.check_mut_borrowing_layout_constrained_field(place);
-                    }
+                }
+                let is_borrow_of_interior_mut = context.is_borrow() && !base
+                    .ty(self.mir, self.tcx)
+                    .to_ty(self.tcx)
+                    .is_freeze(self.tcx, self.param_env, self.source_info.span);
+                if context.is_mutating_use() || is_borrow_of_interior_mut {
+                    self.check_mut_borrowing_layout_constrained_field(
+                        place, context.is_mutating_use(),
+                    );
                 }
                 let old_source_info = self.source_info;
                 if let &Place::Local(local) = base {
@@ -360,6 +362,7 @@ fn register_violations(&mut self,
     fn check_mut_borrowing_layout_constrained_field(
         &mut self,
         mut place: &Place<'tcx>,
+        is_mut_use: bool,
     ) {
         while let &Place::Projection(box Projection {
             ref base, ref elem
@@ -371,17 +374,26 @@ fn check_mut_borrowing_layout_constrained_field(
                         ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) {
                             (Bound::Unbounded, Bound::Unbounded) => {},
                             _ => {
+                                let (description, details) = if is_mut_use {
+                                    (
+                                        "mutation of layout constrained field",
+                                        "mutating layout constrained fields cannot statically be \
+                                        checked for valid values",
+                                    )
+                                } else {
+                                    (
+                                        "borrow of layout constrained field with interior \
+                                        mutability",
+                                        "references to fields of layout constrained fields \
+                                        lose the constraints. Coupled with interior mutability, \
+                                        the field can be changed to invalid values",
+                                    )
+                                };
                                 let source_info = self.source_info;
                                 self.register_violations(&[UnsafetyViolation {
                                     source_info,
-                                    description: Symbol::intern(
-                                        "borrow of layout constrained field",
-                                    ).as_interned_str(),
-                                    details:
-                                        Symbol::intern(
-                                            "references to fields of layout constrained fields \
-                                            lose the constraints",
-                                        ).as_interned_str(),
+                                    description: Symbol::intern(description).as_interned_str(),
+                                    details: Symbol::intern(details).as_interned_str(),
                                     kind: UnsafetyViolationKind::MinConstFn,
                                 }], &[]);
                             }
index 3738b7f5af4a7735ff1870a82c47db1ebd252dde..68ba120b279c02a80bdde064cea4bd3fe7f581ba 100644 (file)
@@ -5,5 +5,5 @@
 pub(crate) struct NonZero<T>(pub(crate) T);
 fn main() {
     let mut x = unsafe { NonZero(1) };
-    let y = &mut x.0; //~ ERROR borrow of layout constrained field is unsafe
+    let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe
 }
index 77313f27a420babea4b6d199ac36a262a61ff0d6..ae63f47ed74a7b6bb2f2d0922eb43636bd5f23ae 100644 (file)
@@ -1,10 +1,10 @@
-error[E0133]: borrow of layout constrained field is unsafe and requires unsafe function or block
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
   --> $DIR/ranged_ints2.rs:8:13
    |
-LL |     let y = &mut x.0; //~ ERROR borrow of layout constrained field is unsafe
-   |             ^^^^^^^^ borrow of layout constrained field
+LL |     let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe
+   |             ^^^^^^^^ mutation of layout constrained field
    |
-   = note: references to fields of layout constrained fields lose the constraints
+   = note: mutating layout constrained fields cannot statically be checked for valid values
 
 error: aborting due to previous error
 
index d68c712227af232e2fec23f2a9805c7feafbcfbb..47d67fac6785c651f030b15970cc7d16caea7dd4 100644 (file)
@@ -7,5 +7,5 @@
 pub(crate) struct NonZero<T>(pub(crate) T);
 fn main() {
     let mut x = unsafe { NonZero(Cell::new(1)) };
-    let y = &x.0; //~ ERROR borrow of layout constrained field is unsafe
+    let y = &x.0; //~ ERROR borrow of layout constrained field with interior mutability
 }
index b5aa9089b5f62ecc0f63d7c5c935c0f787ae522e..311a058fdb07f81e8f7e8447fd705428b7d1bdf4 100644 (file)
@@ -1,10 +1,10 @@
-error[E0133]: borrow of layout constrained field is unsafe and requires unsafe function or block
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
   --> $DIR/ranged_ints3.rs:10:13
    |
-LL |     let y = &x.0; //~ ERROR borrow of layout constrained field is unsafe
-   |             ^^^^ borrow of layout constrained field
+LL |     let y = &x.0; //~ ERROR borrow of layout constrained field with interior mutability
+   |             ^^^^ borrow of layout constrained field with interior mutability
    |
-   = note: references to fields of layout constrained fields lose the constraints
+   = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsafe/ranged_ints4.rs b/src/test/ui/unsafe/ranged_ints4.rs
new file mode 100644 (file)
index 0000000..d8632c4
--- /dev/null
@@ -0,0 +1,9 @@
+#![feature(rustc_attrs)]
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+    let mut x = unsafe { NonZero(1) };
+    x.0 = 0; //~ ERROR mutation of layout constrained field is unsafe
+}
diff --git a/src/test/ui/unsafe/ranged_ints4.stderr b/src/test/ui/unsafe/ranged_ints4.stderr
new file mode 100644 (file)
index 0000000..c6468b6
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+  --> $DIR/ranged_ints4.rs:8:5
+   |
+LL |     x.0 = 0; //~ ERROR mutation of layout constrained field is unsafe
+   |     ^^^^^^^ mutation of layout constrained field
+   |
+   = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.