I do agree for impl Fn() -> Lt<'a> but not for the simple function type. Panicking was more or less meant as an example merely for sake of proving outright that this type is always inhabited regardless of the original lifetime bound, thus making the relaxation useful. A pure function pointer simply can not contain any state itself currently, so there is nothing that could become invalid. However it conjures up (or doesn't) the return type is an entirely separate problem. Note also that for co-variant return types (e.g. &'a T is a subtype of &'static T) it is entirely feasible to write a 'static function returning by having it return the 'static version. Since there is no lifetime-dispatch in the type system such a function is compatible with any 'smaller' output lifetime.
Also, I'm not arguing for changing any variance on functions or even making it bivariant. I'm arguing for treating them as an actually empty type instead of one containing PhantomData<(T0, … Ti)> for the purpose of checking lifetime bounds, not for subtyping relationships. That's a bit weird I assume (and probably somewhat complicated to fully establish in theory) but it can be solved by adding a deduction rule, not restricting any currently.
According to your definition, you cannot return a value with a lifetime less than 'static from a function with an unbound lifetime. This means that the return type is lying - it's return type is not what it is defined to be. I think it's reasonable that unsafe code expect it can return any correct (valid and satisfying any user-defined safety invariants of the type) value of the return type from an fn-ptr (barring any additional requirements it must uphold). If it returns a &'a i32, it should be able to return any &i32 borrowed for at least 'a, and, in particular, should be able to return at any time the function is called provided such a valid value can be produced (so fn()->! cannot return, but fn()->() can).
Further, as mentioned, even if it could not possibly produce a &'a i32, you cannot statically call it outside of 'a, because then you would statically hold a &'a i32 outside of 'a lifetime - a borrowck violation.
These two are subtype related fn() -> &'static str <: fn() -> &'a str by not my definition but the accepted one of covariance in output types. All static references are valid as 'a reference, so all functions of the former are valid as functions of the latter type. That makes it, in theory, perfectly okay to turn the former into the latter.
In other words, it is possible to implement functions with such output types simply by overgeneralizing.
Because a valid implementation exists, it overrides others, even if the it is if the other possible implementations require unsafe to achieve?
As I mentioned, unsafe code should have the right to assume it can return any correct value of the return type from a function within it's own restrictions. This is not different from a function returning a u32: I can write one that returns 5, just as much as 4, 3, 2, or any other value between 0 and u32::MAX. It seems unreasonable that I cannot produce a function that returns a &'a i32 that is, in fact, a &'a i32, instead of an &'static i32, even if it is impossible to produce such a function using purely safe code.
I'm not wanting to do anything to crates. There are plenty of crates relying on incorrect soundness assumptions and enforcing them is not destructive. I was asking for someone to explain the in a more formal step-by-step way based on just the Rust stability promises. If you want to introduce a new type to the language, let alone a lang-item, it's pretty reasonable to want to know how this affects the ability to perform future changes. Given that it seems to be included I'm satisfied with the result, not your explanation of it.
It doesn't even need to be part of the language, you can already use it today with no additional language support. It's just slightly lacking on ergonomics as you can't have DerefMove.
I see that. Now that I'm more convinced of the soundness of the construction it seems very cute. Very good find! Just don't get so personal next time, I ignored your responses for most of the thread as quite some of it was strawman assumptions.
You kept ignoring our responses because... you didn't want to try and explain what you were trying to say? We still don't see how you weren't arguing that existing crates should become unsound.
(We do see that you weren't meaning to do that, but we don't understand what you were saying. Sorry.)