Also make immutable references to non-freeze restricted value range types unsafe
This commit is contained in:
parent
081c49783f
commit
1894a5fe2c
5 changed files with 33 additions and 6 deletions
|
@ -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> {}
|
||||
|
|
|
@ -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> {}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
11
src/test/ui/unsafe/ranged_ints3.rs
Normal file
11
src/test/ui/unsafe/ranged_ints3.rs
Normal file
|
@ -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
|
||||
}
|
11
src/test/ui/unsafe/ranged_ints3.stderr
Normal file
11
src/test/ui/unsafe/ranged_ints3.stderr
Normal file
|
@ -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`.
|
Loading…
Add table
Reference in a new issue