Visit patterns in THIR let expressions
This fixes some THIR unsafety checking errors not being emitted for let expressions in these situations.
This commit is contained in:
parent
2b59992736
commit
868de8e76b
@ -66,8 +66,9 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
|
||||
Use { source } => visitor.visit_expr(&visitor.thir()[source]),
|
||||
NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
|
||||
PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
|
||||
Let { expr, .. } => {
|
||||
Let { expr, ref pat } => {
|
||||
visitor.visit_expr(&visitor.thir()[expr]);
|
||||
visitor.visit_pat(pat);
|
||||
}
|
||||
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
|
||||
Match { scrutinee, ref arms, .. } => {
|
||||
|
@ -495,14 +495,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Let { expr: expr_id, .. } => {
|
||||
let let_expr = &self.thir[expr_id];
|
||||
if let ty::Adt(adt_def, _) = let_expr.ty.kind()
|
||||
&& adt_def.is_union()
|
||||
{
|
||||
self.requires_unsafe(expr.span, AccessToUnionField);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_expr(self, expr);
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:33:5
|
||||
--> $DIR/union-unsafe.rs:34:5
|
||||
|
|
||||
LL | *(u.p) = 13;
|
||||
| ^^^^^^^^^^^ access to union field
|
||||
@ -7,7 +7,7 @@ LL | *(u.p) = 13;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:46:6
|
||||
--> $DIR/union-unsafe.rs:47:6
|
||||
|
|
||||
LL | *u3.a = T::default();
|
||||
| ^^^^ access to union field
|
||||
@ -15,7 +15,7 @@ LL | *u3.a = T::default();
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:52:6
|
||||
--> $DIR/union-unsafe.rs:53:6
|
||||
|
|
||||
LL | *u3.a = T::default();
|
||||
| ^^^^ access to union field
|
||||
@ -23,7 +23,7 @@ LL | *u3.a = T::default();
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:60:13
|
||||
--> $DIR/union-unsafe.rs:61:13
|
||||
|
|
||||
LL | let a = u1.a;
|
||||
| ^^^^ access to union field
|
||||
@ -31,7 +31,7 @@ LL | let a = u1.a;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:63:14
|
||||
--> $DIR/union-unsafe.rs:64:14
|
||||
|
|
||||
LL | let U1 { a } = u1;
|
||||
| ^ access to union field
|
||||
@ -39,7 +39,7 @@ LL | let U1 { a } = u1;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:64:12
|
||||
--> $DIR/union-unsafe.rs:65:12
|
||||
|
|
||||
LL | if let U1 { a: 12 } = u1 {}
|
||||
| ^^^^^^^^^^^^ access to union field
|
||||
@ -47,7 +47,15 @@ LL | if let U1 { a: 12 } = u1 {}
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:69:6
|
||||
--> $DIR/union-unsafe.rs:66:12
|
||||
|
|
||||
LL | if let Some(U1 { a: 13 }) = Some(u1) {}
|
||||
| ^^^^^^^^^^^^^^^^^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:71:6
|
||||
|
|
||||
LL | *u2.a = String::from("new");
|
||||
| ^^^^ access to union field
|
||||
@ -55,7 +63,7 @@ LL | *u2.a = String::from("new");
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:73:6
|
||||
--> $DIR/union-unsafe.rs:75:6
|
||||
|
|
||||
LL | *u3.a = 1;
|
||||
| ^^^^ access to union field
|
||||
@ -63,13 +71,13 @@ LL | *u3.a = 1;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:77:6
|
||||
--> $DIR/union-unsafe.rs:79:6
|
||||
|
|
||||
LL | *u3.a = String::from("new");
|
||||
| ^^^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
||||
|
@ -1,30 +1,31 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::cell::RefCell;
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
union U1 {
|
||||
a: u8
|
||||
a: u8,
|
||||
}
|
||||
|
||||
union U2 {
|
||||
a: ManuallyDrop<String>
|
||||
a: ManuallyDrop<String>,
|
||||
}
|
||||
|
||||
union U3<T> {
|
||||
a: ManuallyDrop<T>
|
||||
a: ManuallyDrop<T>,
|
||||
}
|
||||
|
||||
union U4<T: Copy> {
|
||||
a: T
|
||||
a: T,
|
||||
}
|
||||
|
||||
union URef {
|
||||
p: &'static mut i32,
|
||||
}
|
||||
|
||||
union URefCell { // field that does not drop but is not `Copy`, either
|
||||
union URefCell {
|
||||
// field that does not drop but is not `Copy`, either
|
||||
a: (ManuallyDrop<RefCell<i32>>, i32),
|
||||
}
|
||||
|
||||
@ -62,6 +63,7 @@ fn main() {
|
||||
|
||||
let U1 { a } = u1; //~ ERROR access to union field is unsafe
|
||||
if let U1 { a: 12 } = u1 {} //~ ERROR access to union field is unsafe
|
||||
if let Some(U1 { a: 13 }) = Some(u1) {} //~ ERROR access to union field is unsafe
|
||||
// let U1 { .. } = u1; // OK
|
||||
|
||||
let mut u2 = U2 { a: ManuallyDrop::new(String::from("old")) }; // OK
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:33:6
|
||||
--> $DIR/union-unsafe.rs:34:6
|
||||
|
|
||||
LL | *(u.p) = 13;
|
||||
| ^^^^^ access to union field
|
||||
@ -7,7 +7,7 @@ LL | *(u.p) = 13;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:46:6
|
||||
--> $DIR/union-unsafe.rs:47:6
|
||||
|
|
||||
LL | *u3.a = T::default();
|
||||
| ^^^^ access to union field
|
||||
@ -15,7 +15,7 @@ LL | *u3.a = T::default();
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:52:6
|
||||
--> $DIR/union-unsafe.rs:53:6
|
||||
|
|
||||
LL | *u3.a = T::default();
|
||||
| ^^^^ access to union field
|
||||
@ -23,7 +23,7 @@ LL | *u3.a = T::default();
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:60:13
|
||||
--> $DIR/union-unsafe.rs:61:13
|
||||
|
|
||||
LL | let a = u1.a;
|
||||
| ^^^^ access to union field
|
||||
@ -31,7 +31,7 @@ LL | let a = u1.a;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:63:14
|
||||
--> $DIR/union-unsafe.rs:64:14
|
||||
|
|
||||
LL | let U1 { a } = u1;
|
||||
| ^ access to union field
|
||||
@ -39,15 +39,23 @@ LL | let U1 { a } = u1;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:64:8
|
||||
--> $DIR/union-unsafe.rs:65:20
|
||||
|
|
||||
LL | if let U1 { a: 12 } = u1 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ access to union field
|
||||
| ^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:69:6
|
||||
--> $DIR/union-unsafe.rs:66:25
|
||||
|
|
||||
LL | if let Some(U1 { a: 13 }) = Some(u1) {}
|
||||
| ^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:71:6
|
||||
|
|
||||
LL | *u2.a = String::from("new");
|
||||
| ^^^^ access to union field
|
||||
@ -55,7 +63,7 @@ LL | *u2.a = String::from("new");
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:73:6
|
||||
--> $DIR/union-unsafe.rs:75:6
|
||||
|
|
||||
LL | *u3.a = 1;
|
||||
| ^^^^ access to union field
|
||||
@ -63,13 +71,13 @@ LL | *u3.a = 1;
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/union-unsafe.rs:77:6
|
||||
--> $DIR/union-unsafe.rs:79:6
|
||||
|
|
||||
LL | *u3.a = String::from("new");
|
||||
| ^^^^ access to union field
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
||||
|
@ -6,6 +6,14 @@ LL | let y = &mut x.0;
|
||||
|
|
||||
= note: mutating layout constrained fields cannot statically be checked for valid values
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
|
||||
--> $DIR/ranged_ints2.rs:12:25
|
||||
|
|
||||
LL | if let Some(NonZero(ref mut y)) = Some(x) {}
|
||||
| ^^^^^^^^^ mutation of layout constrained field
|
||||
|
|
||||
= note: mutating layout constrained fields cannot statically be checked for valid values
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
||||
|
@ -9,4 +9,5 @@ pub(crate) struct NonZero<T>(pub(crate) T);
|
||||
fn main() {
|
||||
let mut x = unsafe { NonZero(1) };
|
||||
let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe
|
||||
if let Some(NonZero(ref mut y)) = Some(x) {} //~ ERROR mutation of layout constrained field is unsafe
|
||||
}
|
||||
|
@ -6,6 +6,14 @@ LL | let y = &mut x.0;
|
||||
|
|
||||
= note: mutating layout constrained fields cannot statically be checked for valid values
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
|
||||
--> $DIR/ranged_ints2.rs:12:25
|
||||
|
|
||||
LL | if let Some(NonZero(ref mut y)) = Some(x) {}
|
||||
| ^^^^^^^^^ mutation of layout constrained field
|
||||
|
|
||||
= note: mutating layout constrained fields cannot statically be checked for valid values
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user