This shows a particularly common misunderstanding. Note that lifetimes don't do anything. They compile to no machine instructions, and they don't affect the generated code or runtime behavior. They are a purely compile-time construct, just like types.
Furthermore, you can't prescribe the lifetime of a value, just like you can't prescribe its type. Given a local variable let x = 42_u32;
the following two lines fail to compile for the exact same reason:
let y: String = x; // wrong, type of x is not String
let ptr: &'static u32 = &x; // wrong, lifetime of x is not 'static
The lifetime of a value is what it is, based on where it is created (declared) and destroyed (dropped). You can't change this via lifetime annotations. The only way you can change the lifetime of a value is to shuffle your code around, so that construction and destruction of the value takes place in a different scope. Consequently, there's no such thing as "passing a value with a static lifetime", just like there's no "passing a value with a different type".
The only reason you sometimes need to add lifetime annotations is that the compiler is not always smart enough to infer them, just like it's not always smart enough to infer types. (This apparent lack of the compiler's intelligence is sometimes genuine and unintentional, but sometimes, it may even be deliberate. For example, global inference of types would technically be possible, but it is nevertheless undesirable for a number of more involved reasons that I'm not doing to discuss here.)
Therefore, when you add lifetime annotations, you don't tell the compiler to make any values live longer or shorter. Making values live longer is only possible by actually declaring them in a bigger scope. Rather, adding lifetime annotations asks the compiler to typecheck and borrowcheck your code as if these were the actual lifetimes of the values being annotated. If your code typechecks and borrowchecks with the given annotations, then it is memory safe.
But if your code is not actually memory safe, then it will not typecheck and borrowcheck – you can't use lifetime annotations for lying to the compiler about the validity of your references. It is "merely" a mathematical fact and a technical difficulty that it is easier to verify a proof than it is to come up with one. Lifetime annotations are hints from the programmer to the compiler, and the job of the compiler is to prove a theorem – the theorem that "the following program is memory-safe".
For the sake of example, let's say I ask you to prove that the sum of the first N positive integers is N * (N + 1) / 2. Now you might not be able to prove it off the top of your head. But let's say I then give you a hint: you could try proving it for the simplest case N = 1 and then use induction. You would then be able to complete the proof. But if I tried to trick you into proving a contradiction, e.g. if I claimed that the same sum is equal to N ^ 3, you would be able to quickly verify on several examples that this is clearly wrong. And in either case, the presence or the absence of a hint wouldn't affect the fact that the sum is N * (N + 1) / 2, nor would any false claims of mine do so.