opened 12:50PM - 11 Mar 21 UTC
C-bug
Consider this code:
```rust
struct Updater<'m, S: Copy> {
store: &'m mu…t 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 f98721f886ab52d32d62) with:
```text
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 that `S: 'm` was implied by the reference to `S` requiring lifetime `'m`)
- adding `where S: 'm` to `craft_reply()`
- moving the associated functions out of the impl (but I like organising associated functions alongside the methods that use them)
- use `Updater::<'_, S>::craft` instead of `Self::craft` inside the function body
Some comments from the Discord (user `Yandros FR-ES`):
> Basically your `Updater` struct has an implicit bound of `S : 'm` to be well formed. In the "~~good~~ old days", one had to write that bound explicitly in many many places. That was considered cumbersome, given that the existence of a `&'m [mut] S` type already implies this.
> So the compiler was tweaked to elide this bound, when such as type (e.g., `&'m [mut] S` or a wrapper around it, such as `Self`) appears in the function signature.
> Which does not happen in your `craft_reply` function. This means that within the body of the function, the compiler does not know if `S : 'm` holds, and you thus can't name the `Self = Updater<'m, S>` type which needs that bound to hold :smile:
> I'd consider that a bug (and I expect there to be some issue about it already): the outer `impl` block ought to already imply that `S : 'm` holds
(Thread [starts here](https://discord.com/channels/442252698964721669/443150878111694848/819544568193482763).)