about summary refs log tree commit diff
path: root/tests/ui/unsized-locals
diff options
context:
space:
mode:
authormejrs <59372212+mejrs@users.noreply.github.com>2025-07-08 22:37:12 +0200
committermejrs <59372212+mejrs@users.noreply.github.com>2025-07-08 22:37:12 +0200
commit25eb3829e5661ab85067188ca9e6586c29aed6e9 (patch)
tree3ccb9a062c06d5e90c134b08b76b32082518b0e6 /tests/ui/unsized-locals
parent49421d1fa382fba84792e5d5dd7721c1c3e0e46e (diff)
downloadrust-25eb3829e5661ab85067188ca9e6586c29aed6e9.tar.gz
rust-25eb3829e5661ab85067188ca9e6586c29aed6e9.zip
Error on moving unsized values rather than ICE'ing
Diffstat (limited to 'tests/ui/unsized-locals')
-rw-r--r--tests/ui/unsized-locals/unsized-exprs-rpass.rs5
-rw-r--r--tests/ui/unsized-locals/unsized-exprs.stderr12
-rw-r--r--tests/ui/unsized-locals/unsized-non-place-exprs.rs27
-rw-r--r--tests/ui/unsized-locals/unsized-non-place-exprs.stderr81
4 files changed, 118 insertions, 7 deletions
diff --git a/tests/ui/unsized-locals/unsized-exprs-rpass.rs b/tests/ui/unsized-locals/unsized-exprs-rpass.rs
index 54ecd000343..ce31bd63f7c 100644
--- a/tests/ui/unsized-locals/unsized-exprs-rpass.rs
+++ b/tests/ui/unsized-locals/unsized-exprs-rpass.rs
@@ -18,11 +18,6 @@ impl std::ops::Add<i32> for A<[u8]> {
 }
 
 fn main() {
-    udrop::<[u8]>(loop {
-        break *foo();
-    });
-    udrop::<[u8]>(if true { *foo() } else { *foo() });
-    udrop::<[u8]>({ *foo() });
     udrop::<[u8]>((*foo()));
     *afoo() + 42;
     udrop as fn([u8]);
diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr
index 1b61254870f..0455edbe8e7 100644
--- a/tests/ui/unsized-locals/unsized-exprs.stderr
+++ b/tests/ui/unsized-locals/unsized-exprs.stderr
@@ -10,7 +10,11 @@ note: required because it appears within the type `A<[u8]>`
    |
 LL | struct A<X: ?Sized>(X);
    |        ^
-   = note: structs must have a statically known size to be initialized
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-exprs.rs:19:22
+   |
+LL |     udrop::<A<[u8]>>(A { 0: *foo() });
+   |                      ^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/unsized-exprs.rs:21:22
@@ -24,7 +28,11 @@ note: required because it appears within the type `A<[u8]>`
    |
 LL | struct A<X: ?Sized>(X);
    |        ^
-   = note: the return type of a function must have a statically known size
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-exprs.rs:21:22
+   |
+LL |     udrop::<A<[u8]>>(A(*foo()));
+   |                      ^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/unsized-locals/unsized-non-place-exprs.rs b/tests/ui/unsized-locals/unsized-non-place-exprs.rs
new file mode 100644
index 00000000000..d724fcf81a4
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-non-place-exprs.rs
@@ -0,0 +1,27 @@
+//! `#![feature(unsized_fn_params)]` lets you use unsized function parameters. In particular this
+//! is load bearing for `Box<dyn FnOnce()>: FnOnce()`. To do that, borrowck relaxes the requirement
+//! that certain places must be `Sized`. But in #142911 we removed alloca support, so these
+//! arguments cannot be put in temporaries (or ICE at codegen) That means when `unsized_fn_params`
+//! is enabled, we must explicitly check that unsized function arguments are place expressions.
+//!
+//! Also see tests/ui/unsized_locals/unsized-exprs-rpass.rs
+
+#![feature(unsized_fn_params)]
+
+fn foo() -> Box<[u8]> {
+    Box::new(*b"foo")
+}
+
+fn udrop<T: ?Sized>(_x: T) {}
+
+fn main(){
+    // NB The ordering of the following operations matters, otherwise errors get swallowed somehow.
+
+    udrop::<[u8]>(if true { *foo() } else { *foo() }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time
+    udrop::<[u8]>({ *foo() }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time
+    udrop(match foo() { x => *x }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time
+    udrop::<[u8]>({ loop { break *foo(); } }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time
+
+    { *foo() }; //~ERROR the size for values of type `[u8]` cannot be known at compilation time
+    { loop { break *foo(); } }; //~ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
diff --git a/tests/ui/unsized-locals/unsized-non-place-exprs.stderr b/tests/ui/unsized-locals/unsized-non-place-exprs.stderr
new file mode 100644
index 00000000000..f9507e9a888
--- /dev/null
+++ b/tests/ui/unsized-locals/unsized-non-place-exprs.stderr
@@ -0,0 +1,81 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-non-place-exprs.rs:20:19
+   |
+LL |     udrop::<[u8]>(if true { *foo() } else { *foo() });
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-non-place-exprs.rs:20:19
+   |
+LL |     udrop::<[u8]>(if true { *foo() } else { *foo() });
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-non-place-exprs.rs:21:19
+   |
+LL |     udrop::<[u8]>({ *foo() });
+   |                   ^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-non-place-exprs.rs:21:19
+   |
+LL |     udrop::<[u8]>({ *foo() });
+   |                   ^^^^^^^^^^
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-non-place-exprs.rs:22:11
+   |
+LL |     udrop(match foo() { x => *x });
+   |           ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-non-place-exprs.rs:22:11
+   |
+LL |     udrop(match foo() { x => *x });
+   |           ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-non-place-exprs.rs:23:19
+   |
+LL |     udrop::<[u8]>({ loop { break *foo(); } });
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-non-place-exprs.rs:23:19
+   |
+LL |     udrop::<[u8]>({ loop { break *foo(); } });
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-non-place-exprs.rs:25:5
+   |
+LL |     { *foo() };
+   |     ^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-non-place-exprs.rs:25:5
+   |
+LL |     { *foo() };
+   |     ^^^^^^^^^^
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-non-place-exprs.rs:26:5
+   |
+LL |     { loop { break *foo(); } };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: unsized values must be place expressions and cannot be put in temporaries
+  --> $DIR/unsized-non-place-exprs.rs:26:5
+   |
+LL |     { loop { break *foo(); } };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.