Skip to content

Commit e6d2b2a

Browse files
committed
refactor Box<! -> dyn Error> regression test
1 parent 3432ff9 commit e6d2b2a

File tree

2 files changed

+40
-41
lines changed

2 files changed

+40
-41
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
2+
--> $DIR/coerce-issue-49593-box-never.rs:28:5
3+
|
4+
LL | Box::new(x)
5+
| ^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
6+
|
7+
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
8+
9+
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
10+
--> $DIR/coerce-issue-49593-box-never.rs:33:5
11+
|
12+
LL | raw_ptr(x)
13+
| ^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
14+
|
15+
= note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,37 @@
1-
//@ revisions: nofallback fallback
2-
//@[fallback] edition: 2024
3-
//@[fallback] check-pass
1+
// Regression test for <https://github.com/rust-lang/rust/issues/49593>.
2+
//
3+
// This checks that we can construct `Box<dyn Error>` by calling `Box::new`
4+
// with a value of the never type. And similarly for raw pointers.
5+
//
6+
// This used to fail because we tried to coerce `! -> dyn Error`, which then
7+
// failed because we were trying to pass an unsized value by value, etc.
8+
//
9+
// On edition <= 2021 this currently fails because of never type fallback to
10+
// unit.
11+
//
12+
//@ revisions: e2021 e2024
13+
//@[e2021] edition: 2021
14+
//@[e2024] edition: 2024
15+
//
16+
//@[e2024] check-pass
417

518
#![feature(never_type)]
619

720
use std::error::Error;
821
use std::mem;
922

10-
fn raw_ptr_box<T>(t: T) -> *mut T {
23+
fn raw_ptr<T>(t: T) -> *mut T {
1124
panic!()
1225
}
1326

1427
fn foo(x: !) -> Box<dyn Error> {
15-
// Method resolution will generate new inference vars and relate them.
16-
// Thus fallback will not fall back to `!`, but `()` instead.
17-
Box::<_ /* ! */>::new(x)
18-
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
28+
Box::new(x)
29+
//[e2021]~^ ERROR trait bound `(): std::error::Error` is not satisfied
1930
}
2031

2132
fn foo_raw_ptr(x: !) -> *mut dyn Error {
22-
/* *mut $0 is coerced to *mut Error here */
23-
raw_ptr_box::<_ /* ! */>(x)
24-
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
25-
}
26-
27-
fn no_coercion(d: *mut dyn Error) -> *mut dyn Error {
28-
/* an unsize coercion won't compile here, and it is indeed not used
29-
because there is nothing requiring the _ to be Sized */
30-
d as *mut _
31-
}
32-
33-
trait Xyz {}
34-
struct S;
35-
struct T;
36-
impl Xyz for S {}
37-
impl Xyz for T {}
38-
39-
fn foo_no_never() {
40-
let mut x /* : Option<S> */ = None;
41-
let mut first_iter = false;
42-
loop {
43-
if !first_iter {
44-
let y: Box<dyn Xyz>
45-
= /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
46-
}
47-
48-
x = Some(S);
49-
first_iter = true;
50-
}
51-
52-
let mut y: Option<S> = None;
53-
// assert types are equal
54-
mem::swap(&mut x, &mut y);
33+
raw_ptr(x)
34+
//[e2021]~^ ERROR trait bound `(): std::error::Error` is not satisfied
5535
}
5636

5737
fn main() {}

0 commit comments

Comments
 (0)