For the reference to be returned, it needs to reference a point in memory which isn't freed at the end of the execution of the function.
In the first case you're returning a reference to a value which is on the stack. Such value is usually there because it's dynamically produced. This value is going away when your function ends so the reference points towards nothing then, it's not valid anymore.
In the second and third case, you're returning a reference to a literal, that is to a part of the application's binary. This value isn't going away so the reference is valid. An equivalent of those cases would be
const V: i32 = 200;
fn produce_ref<'a>() -> &'a i32 {
let v = &V;
&v
}