Inside your collect_hash function you create a new String, which is owned data that is dropped at the end of the scope of the function. Because the string instance is dropped when collect_hash finishes, you can't return anything that contains a reference to the string, because said reference would be dangling. Strings can be leaked, but I suggest you change your interface such that the HashSet stores owned data or Cow<'a, str> or something like that.
You're entirely overlooking the ownership aspect of it.
The lifetimes track where data is borrowed from. &str isn't a string itself, it's a temporary view into a string stored elsewhere.
It doesn't make sense to have a function without arguments that returns a borrowed type. You need to have some place to borrow from. You can't lend anything created in the function, because all local variables are destroyed when the function returns.
To add to that, the reason why fn get_str<'a>() -> &'a str works is because it borrows from a constant value in static memory. A string literal ("something") gets the type &'static str, is baked into the program, and is available for its entire duration. The 'static lifetime can always be narrowed down to a shorter lifetime, as in your example, but not the other way around.