about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-18 17:05:44 -0400
committerMichael Goulet <michael@errs.io>2024-09-18 19:17:38 -0400
commite138e8760da3d75def4d23567ae944d65b2d4e89 (patch)
tree3a527eefa0e73b9c050c3ae9001c6ec68795618c
parentf79a912d9edc3ad4db910c0e93672ed5c65133fa (diff)
downloadrust-e138e8760da3d75def4d23567ae944d65b2d4e89.tar.gz
rust-e138e8760da3d75def4d23567ae944d65b2d4e89.zip
Never patterns constitute a read for unsafety
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs9
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs16
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr20
3 files changed, 41 insertions, 4 deletions
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index c7fcfe3ce2a..198698d06fa 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -315,14 +315,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 | PatKind::DerefPattern { .. }
                 | PatKind::Range { .. }
                 | PatKind::Slice { .. }
-                | PatKind::Array { .. } => {
+                | PatKind::Array { .. }
+                // Never constitutes a witness of uninhabitedness.
+                | PatKind::Never => {
                     self.requires_unsafe(pat.span, AccessToUnionField);
                     return; // we can return here since this already requires unsafe
                 }
-                // wildcard/never don't take anything
+                // wildcard doesn't read anything.
                 PatKind::Wild |
-                PatKind::Never |
-                // these just wrap other patterns
+                // these just wrap other patterns, which we recurse on below.
                 PatKind::Or { .. } |
                 PatKind::InlineConstant { .. } |
                 PatKind::AscribeUserType { .. } |
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs
new file mode 100644
index 00000000000..a66c4464417
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs
@@ -0,0 +1,16 @@
+// Make sure we consider `!` to be a union read.
+
+#![feature(never_type, never_patterns)]
+//~^ WARN the feature `never_patterns` is incomplete
+
+union U {
+    a: !,
+    b: usize,
+}
+
+fn foo<T>(u: U) -> ! {
+    let U { a: ! } = u;
+    //~^ ERROR access to union field is unsafe
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr
new file mode 100644
index 00000000000..d7dc7a47e72
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr
@@ -0,0 +1,20 @@
+warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/never-pattern-is-a-read.rs:3:24
+   |
+LL | #![feature(never_type, never_patterns)]
+   |                        ^^^^^^^^^^^^^^
+   |
+   = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/never-pattern-is-a-read.rs:12:16
+   |
+LL |     let U { a: ! } = u;
+   |                ^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0133`.