|
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 |
4 | 17 |
|
5 | 18 | #![feature(never_type)] |
6 | 19 |
|
7 | 20 | use std::error::Error; |
8 | 21 | use std::mem; |
9 | 22 |
|
10 | | -fn raw_ptr_box<T>(t: T) -> *mut T { |
| 23 | +fn raw_ptr<T>(t: T) -> *mut T { |
11 | 24 | panic!() |
12 | 25 | } |
13 | 26 |
|
14 | 27 | 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 |
19 | 30 | } |
20 | 31 |
|
21 | 32 | 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 |
55 | 35 | } |
56 | 36 |
|
57 | 37 | fn main() {} |
0 commit comments