about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2024-05-13 21:14:15 -0400
committerGitHub <noreply@github.com>2024-05-13 21:14:15 -0400
commit18d9c039bb83483c5b1bfec2ebc333d0462c508d (patch)
treea32bc454d0439c89eb1c3555d1d59ea19ee0b39f
parent74a78af0e2e90a1cb0d5f509549f5d9dffc614dc (diff)
parentfb619ec208b898bad1505c97ee79408b2c60926b (diff)
downloadrust-18d9c039bb83483c5b1bfec2ebc333d0462c508d.tar.gz
rust-18d9c039bb83483c5b1bfec2ebc333d0462c508d.zip
Rollup merge of #124997 - gurry:124848-ice-should-be-sized, r=Nadrieril
Fix ICE while casting a type with error

Fixes #124848

The ICE originates here: https://github.com/rust-lang/rust/blob/f9a3fd966162b3c7386d90fe4626471f66ba3b8f/compiler/rustc_hir_typeck/src/cast.rs#L143 The underlying cause is that a type with error, `MyType` was involved in a cast. During cast checks the below method `pointer_kind` was called: https://github.com/rust-lang/rust/blob/f9a3fd966162b3c7386d90fe4626471f66ba3b8f/compiler/rustc_hir_typeck/src/cast.rs#L87-L91 Thanks to the changes in PR #123491, `type_is_sized_modulo_regions` in `pointer_kind` returned `false` which caused control to reach the `span_bug` here: https://github.com/rust-lang/rust/blob/f9a3fd966162b3c7386d90fe4626471f66ba3b8f/compiler/rustc_hir_typeck/src/cast.rs#L143 resulting in an ICE.

This PR fixes the issue by changing the `span_bug` to a `span_delayed_bug`.
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs5
-rw-r--r--tests/ui/cast/ice-cast-type-with-error-124848.rs18
-rw-r--r--tests/ui/cast/ice-cast-type-with-error-124848.stderr63
3 files changed, 85 insertions, 1 deletions
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 316a2bf08cb..9e9a1f678ed 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -141,7 +141,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             | ty::Never
             | ty::Dynamic(_, _, ty::DynStar)
             | ty::Error(_) => {
-                self.dcx().span_bug(span, format!("`{t:?}` should be sized but is not?"));
+                let guar = self
+                    .dcx()
+                    .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
+                return Err(guar);
             }
         })
     }
diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs
new file mode 100644
index 00000000000..9b3732b02db
--- /dev/null
+++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs
@@ -0,0 +1,18 @@
+// Regression test for ICE #124848
+// Tests that there is no ICE when a cast
+// involves a type with error
+
+use std::cell::Cell;
+
+struct MyType<'a>(Cell<Option<&'unpinned mut MyType<'a>>>, Pin);
+//~^ ERROR use of undeclared lifetime name `'unpinned`
+//~| ERROR cannot find type `Pin` in this scope
+
+fn main() {
+    let mut unpinned = MyType(Cell::new(None));
+    //~^ ERROR his struct takes 2 arguments but 1 argument was supplied
+    let bad_addr = &unpinned as *const Cell<Option<&'a mut MyType<'a>>> as usize;
+    //~^ ERROR use of undeclared lifetime name `'a`
+    //~| ERROR use of undeclared lifetime name `'a`
+    //~| ERROR casting `&MyType<'_>` as `*const Cell<Option<&mut MyType<'_>>>` is invalid
+}
diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr
new file mode 100644
index 00000000000..2d86bf76d11
--- /dev/null
+++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr
@@ -0,0 +1,63 @@
+error[E0261]: use of undeclared lifetime name `'unpinned`
+  --> $DIR/ice-cast-type-with-error-124848.rs:7:32
+   |
+LL | struct MyType<'a>(Cell<Option<&'unpinned mut MyType<'a>>>, Pin);
+   |               -                ^^^^^^^^^ undeclared lifetime
+   |               |
+   |               help: consider introducing lifetime `'unpinned` here: `'unpinned,`
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/ice-cast-type-with-error-124848.rs:14:53
+   |
+LL | fn main() {
+   |        - help: consider introducing lifetime `'a` here: `<'a>`
+...
+LL |     let bad_addr = &unpinned as *const Cell<Option<&'a mut MyType<'a>>> as usize;
+   |                                                     ^^ undeclared lifetime
+
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/ice-cast-type-with-error-124848.rs:14:67
+   |
+LL | fn main() {
+   |        - help: consider introducing lifetime `'a` here: `<'a>`
+...
+LL |     let bad_addr = &unpinned as *const Cell<Option<&'a mut MyType<'a>>> as usize;
+   |                                                                   ^^ undeclared lifetime
+
+error[E0412]: cannot find type `Pin` in this scope
+  --> $DIR/ice-cast-type-with-error-124848.rs:7:60
+   |
+LL | struct MyType<'a>(Cell<Option<&'unpinned mut MyType<'a>>>, Pin);
+   |                                                            ^^^ not found in this scope
+   |
+help: consider importing this struct
+   |
+LL + use std::pin::Pin;
+   |
+
+error[E0061]: this struct takes 2 arguments but 1 argument was supplied
+  --> $DIR/ice-cast-type-with-error-124848.rs:12:24
+   |
+LL |     let mut unpinned = MyType(Cell::new(None));
+   |                        ^^^^^^----------------- an argument is missing
+   |
+note: tuple struct defined here
+  --> $DIR/ice-cast-type-with-error-124848.rs:7:8
+   |
+LL | struct MyType<'a>(Cell<Option<&'unpinned mut MyType<'a>>>, Pin);
+   |        ^^^^^^
+help: provide the argument
+   |
+LL |     let mut unpinned = MyType(Cell::new(None), /* value */);
+   |                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0606]: casting `&MyType<'_>` as `*const Cell<Option<&mut MyType<'_>>>` is invalid
+  --> $DIR/ice-cast-type-with-error-124848.rs:14:20
+   |
+LL |     let bad_addr = &unpinned as *const Cell<Option<&'a mut MyType<'a>>> as usize;
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0061, E0261, E0412, E0606.
+For more information about an error, try `rustc --explain E0061`.