1 // Variant of diverging-falllback-control-flow that tests
2 // the specific case of a free function with an unconstrained
3 // return type. This captures the pattern we saw in the wild
4 // in the objc crate, where changing the fallback from `!` to `()`
5 // resulted in unsoundness.
9 // revisions: nofallback fallback
11 #![cfg_attr(fallback, feature(never_type, never_type_fallback))]
17 impl UnitReturn
for i32 {}
18 impl UnitReturn
for () {}
20 fn unconstrained_return
<T
: UnitReturn
>() -> T
{
22 let make_unit_fn
: fn() = make_unit
;
23 let ffi
: fn() -> T
= std
::mem
::transmute(make_unit_fn
);
29 // In Ye Olde Days, the `T` parameter of `unconstrained_return`
30 // winds up "entangled" with the `!` type that results from
31 // `panic!`, and hence falls back to `()`. This is kind of unfortunate
32 // and unexpected. When we introduced the `!` type, the original
33 // idea was to change that fallback to `!`, but that would have resulted
34 // in this code no longer compiling (or worse, in some cases it injected
36 let _
= if true { unconstrained_return() }
else { panic!() }
;