diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2018-11-04 13:45:26 +0100 |
|---|---|---|
| committer | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2018-12-04 10:17:36 +0100 |
| commit | 1894a5fe2c72a1e22897026f34e5f9035cc169ff (patch) | |
| tree | 6ed8ba0526340f76b4918ba8159f53f47f4177c0 | |
| parent | 081c49783f5cfc24f66f3ac36244d816567cc120 (diff) | |
| download | rust-1894a5fe2c72a1e22897026f34e5f9035cc169ff.tar.gz rust-1894a5fe2c72a1e22897026f34e5f9035cc169ff.zip | |
Also make immutable references to non-freeze restricted value range types unsafe
| -rw-r--r-- | src/libcore/marker.rs | 2 | ||||
| -rw-r--r-- | src/libcore/nonzero.rs | 9 | ||||
| -rw-r--r-- | src/librustc_mir/transform/check_unsafety.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/unsafe/ranged_ints3.rs | 11 | ||||
| -rw-r--r-- | src/test/ui/unsafe/ranged_ints3.stderr | 11 |
5 files changed, 33 insertions, 6 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 3bcdfabbb24..23f07773f3f 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -596,7 +596,7 @@ mod impls { /// This affects, for example, whether a `static` of that type is /// placed in read-only static memory or writable static memory. #[lang = "freeze"] -unsafe auto trait Freeze {} +pub(crate) unsafe auto trait Freeze {} impl<T: ?Sized> !Freeze for UnsafeCell<T> {} unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 22d93a5301e..a89c6ca60cb 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -11,22 +11,23 @@ //! Exposes the NonZero lang item which provides optimization hints. use ops::{CoerceUnsized, DispatchFromDyn}; +use marker::Freeze; /// A wrapper type for raw pointers and integers that will never be /// NULL or 0 that might allow certain optimizations. #[rustc_layout_scalar_valid_range_start(1)] #[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] -pub(crate) struct NonZero<T>(pub(crate) T); +pub(crate) struct NonZero<T: Freeze>(pub(crate) T); // Do not call `T::clone` as theoretically it could turn the field into `0` // invalidating `NonZero`'s invariant. -impl<T: Copy> Clone for NonZero<T> { +impl<T: Copy + Freeze> Clone for NonZero<T> { fn clone(&self) -> Self { unsafe { NonZero(self.0) } } } -impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {} +impl<T: CoerceUnsized<U> + Freeze, U: Freeze> CoerceUnsized<NonZero<U>> for NonZero<T> {} -impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {} +impl<T: DispatchFromDyn<U> + Freeze, U: Freeze> DispatchFromDyn<NonZero<U>> for NonZero<T> {} diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 2a80f27ecab..c7a785ad2c5 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -187,7 +187,11 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { kind: UnsafetyViolationKind::BorrowPacked(lint_root) }], &[]); } - if context.is_mutating_use() { + 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); } } diff --git a/src/test/ui/unsafe/ranged_ints3.rs b/src/test/ui/unsafe/ranged_ints3.rs new file mode 100644 index 00000000000..d68c712227a --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3.rs @@ -0,0 +1,11 @@ +#![feature(rustc_attrs)] + +use std::cell::Cell; + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +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 +} diff --git a/src/test/ui/unsafe/ranged_ints3.stderr b/src/test/ui/unsafe/ranged_ints3.stderr new file mode 100644 index 00000000000..b5aa9089b5f --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints3.stderr @@ -0,0 +1,11 @@ +error[E0133]: borrow of layout constrained field 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 + | + = note: references to fields of layout constrained fields lose the constraints + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. |
