Skip to content

Commit 8afbe84

Browse files
committed
Visit patterns in THIR let expressions
This fixes some THIR unsafety checking errors not being emitted for let expressions in these situations.
1 parent 9752fd7 commit 8afbe84

File tree

8 files changed

+66
-38
lines changed

8 files changed

+66
-38
lines changed

compiler/rustc_middle/src/thir/visit.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
6666
Use { source } => visitor.visit_expr(&visitor.thir()[source]),
6767
NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
6868
PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
69-
Let { expr, .. } => {
69+
Let { expr, ref pat } => {
7070
visitor.visit_expr(&visitor.thir()[expr]);
71+
visitor.visit_pat(pat);
7172
}
7273
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
7374
Match { scrutinee, ref arms, .. } => {

compiler/rustc_mir_build/src/check_unsafety.rs

-8
Original file line numberDiff line numberDiff line change
@@ -492,14 +492,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
492492
}
493493
}
494494
}
495-
ExprKind::Let { expr: expr_id, .. } => {
496-
let let_expr = &self.thir[expr_id];
497-
if let ty::Adt(adt_def, _) = let_expr.ty.kind()
498-
&& adt_def.is_union()
499-
{
500-
self.requires_unsafe(expr.span, AccessToUnionField);
501-
}
502-
}
503495
_ => {}
504496
}
505497
visit::walk_expr(self, expr);
+18-10
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,83 @@
11
error[E0133]: access to union field is unsafe and requires unsafe function or block
2-
--> $DIR/union-unsafe.rs:33:5
2+
--> $DIR/union-unsafe.rs:34:5
33
|
44
LL | *(u.p) = 13;
55
| ^^^^^^^^^^^ access to union field
66
|
77
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
88

99
error[E0133]: access to union field is unsafe and requires unsafe function or block
10-
--> $DIR/union-unsafe.rs:46:6
10+
--> $DIR/union-unsafe.rs:47:6
1111
|
1212
LL | *u3.a = T::default();
1313
| ^^^^ access to union field
1414
|
1515
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
1616

1717
error[E0133]: access to union field is unsafe and requires unsafe function or block
18-
--> $DIR/union-unsafe.rs:52:6
18+
--> $DIR/union-unsafe.rs:53:6
1919
|
2020
LL | *u3.a = T::default();
2121
| ^^^^ access to union field
2222
|
2323
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
2424

2525
error[E0133]: access to union field is unsafe and requires unsafe function or block
26-
--> $DIR/union-unsafe.rs:60:13
26+
--> $DIR/union-unsafe.rs:61:13
2727
|
2828
LL | let a = u1.a;
2929
| ^^^^ access to union field
3030
|
3131
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
3232

3333
error[E0133]: access to union field is unsafe and requires unsafe function or block
34-
--> $DIR/union-unsafe.rs:63:14
34+
--> $DIR/union-unsafe.rs:64:14
3535
|
3636
LL | let U1 { a } = u1;
3737
| ^ access to union field
3838
|
3939
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
4040

4141
error[E0133]: access to union field is unsafe and requires unsafe function or block
42-
--> $DIR/union-unsafe.rs:64:12
42+
--> $DIR/union-unsafe.rs:65:12
4343
|
4444
LL | if let U1 { a: 12 } = u1 {}
4545
| ^^^^^^^^^^^^ access to union field
4646
|
4747
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
4848

4949
error[E0133]: access to union field is unsafe and requires unsafe function or block
50-
--> $DIR/union-unsafe.rs:69:6
50+
--> $DIR/union-unsafe.rs:66:12
51+
|
52+
LL | if let Some(U1 { a: 13 }) = Some(u1) {}
53+
| ^^^^^^^^^^^^^^^^^^ access to union field
54+
|
55+
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
56+
57+
error[E0133]: access to union field is unsafe and requires unsafe function or block
58+
--> $DIR/union-unsafe.rs:71:6
5159
|
5260
LL | *u2.a = String::from("new");
5361
| ^^^^ access to union field
5462
|
5563
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
5664

5765
error[E0133]: access to union field is unsafe and requires unsafe function or block
58-
--> $DIR/union-unsafe.rs:73:6
66+
--> $DIR/union-unsafe.rs:75:6
5967
|
6068
LL | *u3.a = 1;
6169
| ^^^^ access to union field
6270
|
6371
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
6472

6573
error[E0133]: access to union field is unsafe and requires unsafe function or block
66-
--> $DIR/union-unsafe.rs:77:6
74+
--> $DIR/union-unsafe.rs:79:6
6775
|
6876
LL | *u3.a = String::from("new");
6977
| ^^^^ access to union field
7078
|
7179
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
7280

73-
error: aborting due to 9 previous errors
81+
error: aborting due to 10 previous errors
7482

7583
For more information about this error, try `rustc --explain E0133`.

tests/ui/union/union-unsafe.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
// revisions: mir thir
22
// [thir]compile-flags: -Z thir-unsafeck
33

4-
use std::mem::ManuallyDrop;
54
use std::cell::RefCell;
5+
use std::mem::ManuallyDrop;
66

77
union U1 {
8-
a: u8
8+
a: u8,
99
}
1010

1111
union U2 {
12-
a: ManuallyDrop<String>
12+
a: ManuallyDrop<String>,
1313
}
1414

1515
union U3<T> {
16-
a: ManuallyDrop<T>
16+
a: ManuallyDrop<T>,
1717
}
1818

1919
union U4<T: Copy> {
20-
a: T
20+
a: T,
2121
}
2222

2323
union URef {
2424
p: &'static mut i32,
2525
}
2626

27-
union URefCell { // field that does not drop but is not `Copy`, either
27+
union URefCell {
28+
// field that does not drop but is not `Copy`, either
2829
a: (ManuallyDrop<RefCell<i32>>, i32),
2930
}
3031

@@ -62,6 +63,7 @@ fn main() {
6263

6364
let U1 { a } = u1; //~ ERROR access to union field is unsafe
6465
if let U1 { a: 12 } = u1 {} //~ ERROR access to union field is unsafe
66+
if let Some(U1 { a: 13 }) = Some(u1) {} //~ ERROR access to union field is unsafe
6567
// let U1 { .. } = u1; // OK
6668

6769
let mut u2 = U2 { a: ManuallyDrop::new(String::from("old")) }; // OK
+19-11
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,83 @@
11
error[E0133]: access to union field is unsafe and requires unsafe function or block
2-
--> $DIR/union-unsafe.rs:33:6
2+
--> $DIR/union-unsafe.rs:34:6
33
|
44
LL | *(u.p) = 13;
55
| ^^^^^ access to union field
66
|
77
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
88

99
error[E0133]: access to union field is unsafe and requires unsafe function or block
10-
--> $DIR/union-unsafe.rs:46:6
10+
--> $DIR/union-unsafe.rs:47:6
1111
|
1212
LL | *u3.a = T::default();
1313
| ^^^^ access to union field
1414
|
1515
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
1616

1717
error[E0133]: access to union field is unsafe and requires unsafe function or block
18-
--> $DIR/union-unsafe.rs:52:6
18+
--> $DIR/union-unsafe.rs:53:6
1919
|
2020
LL | *u3.a = T::default();
2121
| ^^^^ access to union field
2222
|
2323
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
2424

2525
error[E0133]: access to union field is unsafe and requires unsafe function or block
26-
--> $DIR/union-unsafe.rs:60:13
26+
--> $DIR/union-unsafe.rs:61:13
2727
|
2828
LL | let a = u1.a;
2929
| ^^^^ access to union field
3030
|
3131
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
3232

3333
error[E0133]: access to union field is unsafe and requires unsafe function or block
34-
--> $DIR/union-unsafe.rs:63:14
34+
--> $DIR/union-unsafe.rs:64:14
3535
|
3636
LL | let U1 { a } = u1;
3737
| ^ access to union field
3838
|
3939
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
4040

4141
error[E0133]: access to union field is unsafe and requires unsafe function or block
42-
--> $DIR/union-unsafe.rs:64:8
42+
--> $DIR/union-unsafe.rs:65:20
4343
|
4444
LL | if let U1 { a: 12 } = u1 {}
45-
| ^^^^^^^^^^^^^^^^^^^^^ access to union field
45+
| ^^ access to union field
4646
|
4747
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
4848

4949
error[E0133]: access to union field is unsafe and requires unsafe function or block
50-
--> $DIR/union-unsafe.rs:69:6
50+
--> $DIR/union-unsafe.rs:66:25
51+
|
52+
LL | if let Some(U1 { a: 13 }) = Some(u1) {}
53+
| ^^ access to union field
54+
|
55+
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
56+
57+
error[E0133]: access to union field is unsafe and requires unsafe function or block
58+
--> $DIR/union-unsafe.rs:71:6
5159
|
5260
LL | *u2.a = String::from("new");
5361
| ^^^^ access to union field
5462
|
5563
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
5664

5765
error[E0133]: access to union field is unsafe and requires unsafe function or block
58-
--> $DIR/union-unsafe.rs:73:6
66+
--> $DIR/union-unsafe.rs:75:6
5967
|
6068
LL | *u3.a = 1;
6169
| ^^^^ access to union field
6270
|
6371
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
6472

6573
error[E0133]: access to union field is unsafe and requires unsafe function or block
66-
--> $DIR/union-unsafe.rs:77:6
74+
--> $DIR/union-unsafe.rs:79:6
6775
|
6876
LL | *u3.a = String::from("new");
6977
| ^^^^ access to union field
7078
|
7179
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
7280

73-
error: aborting due to 9 previous errors
81+
error: aborting due to 10 previous errors
7482

7583
For more information about this error, try `rustc --explain E0133`.

tests/ui/unsafe/ranged_ints2.mirunsafeck.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ LL | let y = &mut x.0;
66
|
77
= note: mutating layout constrained fields cannot statically be checked for valid values
88

9-
error: aborting due to previous error
9+
error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
10+
--> $DIR/ranged_ints2.rs:12:25
11+
|
12+
LL | if let Some(NonZero(ref mut y)) = Some(x) {}
13+
| ^^^^^^^^^ mutation of layout constrained field
14+
|
15+
= note: mutating layout constrained fields cannot statically be checked for valid values
16+
17+
error: aborting due to 2 previous errors
1018

1119
For more information about this error, try `rustc --explain E0133`.

tests/ui/unsafe/ranged_ints2.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ pub(crate) struct NonZero<T>(pub(crate) T);
99
fn main() {
1010
let mut x = unsafe { NonZero(1) };
1111
let y = &mut x.0; //~ ERROR mutation of layout constrained field is unsafe
12+
if let Some(NonZero(ref mut y)) = Some(x) {} //~ ERROR mutation of layout constrained field is unsafe
1213
}

tests/ui/unsafe/ranged_ints2.thirunsafeck.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ LL | let y = &mut x.0;
66
|
77
= note: mutating layout constrained fields cannot statically be checked for valid values
88

9-
error: aborting due to previous error
9+
error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
10+
--> $DIR/ranged_ints2.rs:12:25
11+
|
12+
LL | if let Some(NonZero(ref mut y)) = Some(x) {}
13+
| ^^^^^^^^^ mutation of layout constrained field
14+
|
15+
= note: mutating layout constrained fields cannot statically be checked for valid values
16+
17+
error: aborting due to 2 previous errors
1018

1119
For more information about this error, try `rustc --explain E0133`.

0 commit comments

Comments
 (0)