Skip to content

Commit 1894a5f

Browse files
committedDec 4, 2018

File tree

5 files changed

+33
-6
lines changed

5 files changed

+33
-6
lines changed
 

‎src/libcore/marker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ mod impls {
596596
/// This affects, for example, whether a `static` of that type is
597597
/// placed in read-only static memory or writable static memory.
598598
#[lang = "freeze"]
599-
unsafe auto trait Freeze {}
599+
pub(crate) unsafe auto trait Freeze {}
600600

601601
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
602602
unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}

‎src/libcore/nonzero.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,23 @@
1111
//! Exposes the NonZero lang item which provides optimization hints.
1212
1313
use ops::{CoerceUnsized, DispatchFromDyn};
14+
use marker::Freeze;
1415

1516
/// A wrapper type for raw pointers and integers that will never be
1617
/// NULL or 0 that might allow certain optimizations.
1718
#[rustc_layout_scalar_valid_range_start(1)]
1819
#[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
1920
#[repr(transparent)]
20-
pub(crate) struct NonZero<T>(pub(crate) T);
21+
pub(crate) struct NonZero<T: Freeze>(pub(crate) T);
2122

2223
// Do not call `T::clone` as theoretically it could turn the field into `0`
2324
// invalidating `NonZero`'s invariant.
24-
impl<T: Copy> Clone for NonZero<T> {
25+
impl<T: Copy + Freeze> Clone for NonZero<T> {
2526
fn clone(&self) -> Self {
2627
unsafe { NonZero(self.0) }
2728
}
2829
}
2930

30-
impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}
31+
impl<T: CoerceUnsized<U> + Freeze, U: Freeze> CoerceUnsized<NonZero<U>> for NonZero<T> {}
3132

32-
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {}
33+
impl<T: DispatchFromDyn<U> + Freeze, U: Freeze> DispatchFromDyn<NonZero<U>> for NonZero<T> {}

‎src/librustc_mir/transform/check_unsafety.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
187187
kind: UnsafetyViolationKind::BorrowPacked(lint_root)
188188
}], &[]);
189189
}
190-
if context.is_mutating_use() {
190+
let is_freeze = base
191+
.ty(self.mir, self.tcx)
192+
.to_ty(self.tcx)
193+
.is_freeze(self.tcx, self.param_env, self.source_info.span);
194+
if context.is_mutating_use() || !is_freeze {
191195
self.check_mut_borrowing_layout_constrained_field(place);
192196
}
193197
}

‎src/test/ui/unsafe/ranged_ints3.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(rustc_attrs)]
2+
3+
use std::cell::Cell;
4+
5+
#[rustc_layout_scalar_valid_range_start(1)]
6+
#[repr(transparent)]
7+
pub(crate) struct NonZero<T>(pub(crate) T);
8+
fn main() {
9+
let mut x = unsafe { NonZero(Cell::new(1)) };
10+
let y = &x.0; //~ ERROR borrow of layout constrained field is unsafe
11+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0133]: borrow of layout constrained field is unsafe and requires unsafe function or block
2+
--> $DIR/ranged_ints3.rs:10:13
3+
|
4+
LL | let y = &x.0; //~ ERROR borrow of layout constrained field is unsafe
5+
| ^^^^ borrow of layout constrained field
6+
|
7+
= note: references to fields of layout constrained fields lose the constraints
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0133`.

0 commit comments

Comments
 (0)
Please sign in to comment.