Skip to content

Commit 868de8e

Browse files
committedNov 6, 2023
Visit patterns in THIR let expressions
This fixes some THIR unsafety checking errors not being emitted for let expressions in these situations.
1 parent 2b59992 commit 868de8e

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
@@ -495,14 +495,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
495495
}
496496
}
497497
}
498-
ExprKind::Let { expr: expr_id, .. } => {
499-
let let_expr = &self.thir[expr_id];
500-
if let ty::Adt(adt_def, _) = let_expr.ty.kind()
501-
&& adt_def.is_union()
502-
{
503-
self.requires_unsafe(expr.span, AccessToUnionField);
504-
}
505-
}
506498
_ => {}
507499
}
508500
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)