Improve HRTB compatibility for "lifetime not general enough" cases, or provide better help/notes + update language tutorials

Continuing the discussion from Idea: aliasing the `'static` lifetime for lifetime parameters / trait bounds, e.g., `'auto`:

It became clear that there're misunderstandings included in my original post, and after we discussed about that, I'd extract the root issue as @CAD97 had pointed out:

So basically when I wrote:

fn my_fn<T: for<'a> Into<Cow<'a, str>>>(param: T) {}

so that I can pass either a &'static str or a String as a param, in the former case the compiler complained:

error: implementation of `From` is not general enough
  --> src\**
   |
** |         my_fn("string literal");
   |         ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `From` is not general enough
   |
   = note: `From<&str>` would have to be implemented for the type `Cow<'0, str>`, for any lifetime `'0`...
   = note: ...but `From<&'1 str>` is actually implemented for the type `Cow<'1, str>`, for some specific lifetime `'1`

which is really not helpful, since a string literal (namely &'static str) could be converted to a Cow<'a, str> with any lifetime 'a, if it's just converted to a Cow<'static, str> and then coerced to a Cow<'a, str>.

Fortunately for this specific case (I just need to support &'static str instead of any &'a str), I can write:

fn my_fn<T: Into<Cow<'static, str>>>(param: T) {}

instead, and the code works.

But, if I wrote:

fn my_fn<T: Into<Cow<str>>>(param: T) {}

in the first place, the compiler would hint:

error[E0106]: missing lifetime specifier
  --> src\**
   |
** | fn my_fn<T: Into<Cow<str>>>(param: T) {}
   |                     ^ expected named lifetime parameter
   |
   = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'a` lifetime
   |
** | fn my_fn<T: for<'a> Into<Cow<'a, str>>>(param: T) {}
   |             +++++++          +++
help: consider introducing a named lifetime parameter
   |
** | fn my_fn<'a, T: Into<Cow<'a, str>>>(param: T) {}
   |          +++             +++

So during the whole process, I (as a Rust beginner) had got no guide leading me to the solution to the HRTB "lifetime not general enough" error (when it seems the lifetime in the implementation is actually "general enough", or ready for use).

The ideal fix would be to eliminate the "lifetime not general enough" error in similar cases by improving HRTB compatibility.

If that could not be done (soon enough), then at least I think a better guide is needed to help people figure out that replacing for<'a> Into<Cow<'a, str>> with Into<Cow<'static, str>> might fix the error, as mentioned by @CAD97:

1 Like