mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Also prevent mutation fields directly
This commit is contained in:
parent
1894a5fe2c
commit
55abc0bc90
@ -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,
|
||||
}], &[]);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
9
src/test/ui/unsafe/ranged_ints4.rs
Normal file
9
src/test/ui/unsafe/ranged_ints4.rs
Normal 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
|
||||
}
|
11
src/test/ui/unsafe/ranged_ints4.stderr
Normal file
11
src/test/ui/unsafe/ranged_ints4.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user