Repository: rust
Issue: Lack of HRTB produces nonsense error message, correct syntax isn't even mentioned in The Book
Labels: C-enhancement,A-diagnostics,A-lifetimes,A-trait-system,A-borrow-checker,T-compiler,D-confusing

I hit a weird error case today. It turns out, I hit a problem with lifetimes where the only solution was HRTBs (Higher-Ranked Trait Bounds).

I've tried to condense the reproduction sample as much as possible, without it being utterly abstract:

```rust
use std::io::Result;
use std::fmt::*;

pub trait CanDecode where Self: Sized { fn read(&mut Decoder) -> Result<Self>; }
pub trait CanEncode { fn write(self, &mut Encoder) -> Result<()>; }

pub struct Decoder {}
pub struct Encoder {}


#[derive(Debug)]
struct DataType {}

impl CanDecode for DataType { fn read(_: &mut Decoder) -> Result<Self> { Ok(DataType {}) } }
impl<'a> CanEncode for &'a DataType { fn write(self, _: &mut Encoder) -> Result<()> { Ok(()) } }

fn main()
{
    parse::<DataType>().unwrap();
}

fn parse<'a, P>() -> Result<()> where
    P: CanDecode + Debug,

  /* attempted syntax: */
&'a P: CanEncode,
    P: 'a,

  /* correct syntax */
  // for <'x> &'x P: CanEncode,

{
    let mut rdr = Decoder {};
    let frame = P::read(&mut rdr)?;
    let mut wtr = Encoder {};
    frame.write(&mut wtr)?;
    Ok(())
}
```

Compiling this code:

```
$ rustc --version
rustc 1.19.0-nightly (e17a1227a 2017-05-12)

$ rustc hrtb-ergonomics.rs
error: `frame` does not live long enough
  --> hrtb-ergonomics.rs:36:5
   |
36 |     frame.write(&mut wtr)?;
   |     ^^^^^ does not live long enough
37 |     Ok(())
38 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the body at 32:0...
  --> hrtb-ergonomics.rs:32:1
   |
32 | / {
33 | |     let mut rdr = Decoder {};
34 | |     let frame = P::read(&mut rdr)?;
35 | |     let mut wtr = Encoder {};
36 | |     frame.write(&mut wtr)?;
37 | |     Ok(())
38 | | }
   | |_^

error: aborting due to previous error
```

Replacing the "attempted code" with the "correct syntax" comment makes this compile fine.

For me, this points towards several sub-issues:

 1) The error message is wrong - it should work just fine according to rustc. It's clearly not ergonomic, at least.

 1) HRTBs are not mentioned at all in the book. The `for<'a>` syntax was completely new to me, when I heard about it on IRC. The Nomicon mentions this (with the comment "There aren't many places outside of the Fn traits where we encounter HRTBs, and even for those we have a nice magic sugar for the common cases.")

 1) The code is clearly fine (except for the lifetime annotations), but I don't understand *why* the non-HRTB version doesn't compile. The reference is alive inside the parse() fn, which seems fine to me?

 1) It seems odd to me that I hit a feature that is so obscure that the Nomicon mentions that there "aren't many places" where it is encountered. I don't feel like my code is doing anything super obscure. Is there some other much easier way to express this, that I am missing?

If this issue should be split up into multiple issues, I'd be happy to help - please advice.