From: Oliver Scherer Date: Sat, 3 Nov 2018 15:30:05 +0000 (+0100) Subject: Forbid the creation of mutable borrows to fields of layout constrained types X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=8bdb11c4d94a05c3d6148e52b53a6b95ec9f0a13;p=rust.git Forbid the creation of mutable borrows to fields of layout constrained types --- diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 1e90f5a9584..05052c8a8c8 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -187,6 +187,9 @@ fn visit_place(&mut self, kind: UnsafetyViolationKind::BorrowPacked(lint_root) }], &[]); } + if context.is_mutating_use() { + self.check_mut_borrowing_layout_constrained_field(place); + } } let old_source_info = self.source_info; if let &Place::Local(local) = base { @@ -350,6 +353,43 @@ fn register_violations(&mut self, (node_id, is_used && !within_unsafe) })); } + fn check_mut_borrowing_layout_constrained_field( + &mut self, + mut place: &Place<'tcx>, + ) { + while let &Place::Projection(box Projection { + ref base, ref elem + }) = place { + match *elem { + ProjectionElem::Field(..) => { + let ty = base.ty(&self.mir.local_decls, self.tcx).to_ty(self.tcx); + match ty.sty { + ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) { + (Bound::Unbounded, Bound::Unbounded) => {}, + _ => { + 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(), + kind: UnsafetyViolationKind::MinConstFn, + }], &[]); + } + }, + _ => {} + } + } + _ => {} + } + place = base; + } + } } pub(crate) fn provide(providers: &mut Providers) { diff --git a/src/test/ui/unsafe/ranged_ints.rs b/src/test/ui/unsafe/ranged_ints.rs new file mode 100644 index 00000000000..c9fdadeaf05 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints.rs @@ -0,0 +1,8 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { + let _x = NonZero(0); //~ ERROR initializing type with `rustc_layout_scalar_valid_range` attr +} \ No newline at end of file diff --git a/src/test/ui/unsafe/ranged_ints.stderr b/src/test/ui/unsafe/ranged_ints.stderr new file mode 100644 index 00000000000..c28adba9ee5 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints.stderr @@ -0,0 +1,11 @@ +error[E0133]: initializing type with `rustc_layout_scalar_valid_range` attr is unsafe and requires unsafe function or block + --> $DIR/ranged_ints.rs:7:14 + | +LL | let _x = NonZero(0); //~ ERROR initializing type with `rustc_layout_scalar_valid_range` attr + | ^^^^^^^^^^ initializing type with `rustc_layout_scalar_valid_range` attr + | + = note: initializing `NonZero` with a `0` violates layout constraints and is undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints2.rs b/src/test/ui/unsafe/ranged_ints2.rs new file mode 100644 index 00000000000..9e1acb1a7b1 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2.rs @@ -0,0 +1,9 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(1) }; + let y = &mut x.0; //~ ERROR borrow of layout constrained field is unsafe +} \ No newline at end of file diff --git a/src/test/ui/unsafe/ranged_ints2.stderr b/src/test/ui/unsafe/ranged_ints2.stderr new file mode 100644 index 00000000000..77313f27a42 --- /dev/null +++ b/src/test/ui/unsafe/ranged_ints2.stderr @@ -0,0 +1,11 @@ +error[E0133]: borrow 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 + | + = 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`.