- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Description
Consider this code:
struct Updater<'m, S: Copy> {
    store: &'m mut S,
}
impl<'m, S: Copy> Updater<'m, S> {
    fn craft<T: Copy>(builder: &Vec<T>) {}
    fn craft_reply<T: Copy>(update: Vec<T>)
    {
        Self::craft(&update)
    }       
}It fails to compile on 1.50 and nightly 1.52.0-nightly (2021-03-10 f98721f) with:
   Compiling playground v0.0.1 (/playground)
error[E0309]: the parameter type `S` may not live long enough
  --> src/lib.rs:11:9
   |
5  | impl<'m, S: Copy> Updater<'m, S> {
   |          -- help: consider adding an explicit lifetime bound...: `S: 'm +`
...
11 |         Self::craft(&update)
   |         ^^^^^^^^^^^ ...so that the type `S` will meet its required lifetime bounds
error: aborting due to previous error
For more information about this error, try `rustc --explain E0309`.
error: could not compile `playground`
If I add a &self parameter to craft_reply(), it compiles. I cannot see what needs to be parameterised by the &self lifetime when it's not there, though.
Other things that work:
- using impl<'m, S: Copy + 'm>(but I would have thought thatS: 'mwas implied by the reference toSrequiring lifetime'm)
- adding where S: 'mtocraft_reply()
- moving the associated functions out of the impl (but I like organising associated functions alongside the methods that use them)
- use Updater::<'_, S>::craftinstead ofSelf::craftinside the function body
Some comments from the Discord (user Yandros FR-ES):
Basically your
Updaterstruct has an implicit bound ofS : 'mto be well formed. In the "goodold days", one had to write that bound explicitly in many many places. That was considered cumbersome, given that the existence of a&'m [mut] Stype already implies this.
So the compiler was tweaked to elide this bound, when such as type (e.g.,&'m [mut] Sor a wrapper around it, such asSelf) appears in the function signature.
Which does not happen in yourcraft_replyfunction. This means that within the body of the function, the compiler does not know ifS : 'mholds, and you thus can't name theSelf = Updater<'m, S>type which needs that bound to hold 😄
I'd consider that a bug (and I expect there to be some issue about it already): the outer
implblock ought to already imply thatS : 'mholds
(Thread starts here.)