Also prevent mutation fields directly

This commit is contained in:
Oliver Scherer 2018-11-05 13:26:07 +01:00
parent 1894a5fe2c
commit 55abc0bc90
7 changed files with 57 additions and 25 deletions

View File

@ -187,13 +187,15 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
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 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
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 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
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,
}], &[]);
}

View 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
}

View 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

View File

@ -7,5 +7,5 @@ use std::cell::Cell;
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
}

View 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

View File

@ -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
}

View File

@ -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`.