title: Writing a trait to use multiple database backends gives me "error[E0597]: `connection` does not live long enough"
body: <p>My program needs to be able to read its data from several databases (Postgres and Oracle).</p>
  
  <h1>Original try</h1>
  
  <p>So I thought I would use traits to hide implementations details and a generic function to get at the data. Sadly I need an cheat function to get at the <code>Transaction</code> in the case of Postgres backend:</p>
  
  <pre class="lang-rust prettyprint-override"><code>trait DataSource&lt;'a&gt; {
      fn get_data(&amp;mut self) -&gt; String;
      fn transaction(&amp;mut self) -&gt; &amp;mut postgres::Transaction&lt;'a&gt; {
          unimplemented!()
      }
  }
  
  trait BackendConnection&lt;'a, TS&gt;
  where
      TS: DataSource&lt;'a&gt;,
  {
      fn data_source(&amp;'a mut self) -&gt; TS;
  }
  
  trait BackendConfiguration&lt;'a, TC, TS&gt;
  where
      TC: BackendConnection&lt;'a, TS&gt;,
      TS: DataSource&lt;'a&gt;,
  {
      fn connect(&amp;self) -&gt; TC;
  }
  
  fn generate&lt;'a, TF, TC, TS&gt;(config: &amp;TF)
  where
      TF: BackendConfiguration&lt;'a, TC, TS&gt;,
      TC: BackendConnection&lt;'a, TS&gt; + 'a,
      TS: DataSource&lt;'a&gt; + 'a,
  {
      let mut connection = config.connect();
      let mut source = connection.data_source();
      println!("{:?}", source.get_data());
  }
  
  // You can ignore all this, it is there just to show the reason why the lifetime is needed in `data_source(&amp;'a mut self)` above.
  mod pg {
      pub struct PgSource&lt;'a&gt; {transaction: postgres::Transaction&lt;'a&gt;}
      impl&lt;'a&gt; super::DataSource&lt;'a&gt; for PgSource&lt;'a&gt; {
          fn get_data(&amp;mut self) -&gt; String {
              let mut data = String::new();
              for row in self.transaction.query("SELECT CURRENT_TIMESTAMP", &amp;[]).unwrap() {
                  let st: std::time::SystemTime = row.get(0);
                  data.push_str(&amp;format!("{:?}\n", st));
              }
              data
          }
          fn transaction(&amp;mut self) -&gt; &amp;mut postgres::Transaction&lt;'a&gt; {
              &amp;mut self.transaction
          }
      }
  
      pub struct PgConnection {client: postgres::Client}
      impl&lt;'a&gt; super::BackendConnection&lt;'a, PgSource&lt;'a&gt;&gt; for PgConnection {
          fn data_source(&amp;'a mut self) -&gt; PgSource&lt;'a&gt; {
              let transaction = self.client.transaction().unwrap();
              PgSource { transaction }
          }
      }
  
      pub struct PgConfiguration {config: postgres::Config}
      impl PgConfiguration {
          pub fn new(params: &amp;str) -&gt; Self {
              let config = params.parse::&lt;postgres::Config&gt;().unwrap();
              Self { config }
          }
      }
      impl&lt;'a&gt; super::BackendConfiguration&lt;'a, PgConnection, PgSource&lt;'a&gt;&gt; for PgConfiguration {
          fn connect(&amp;self) -&gt; PgConnection {
              let client = self.config.connect(postgres::tls::NoTls).unwrap();
              PgConnection { client }
          }
      }
  }
  </code></pre>
  
  <p>But the <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=d68aa22eb607315e09827b78369d2ed9" rel="nofollow noreferrer">Rust compiler does not accept this</a>:</p>
  
  <pre><code>error[E0597]: `connection` does not live long enough
    --&gt; src/lib.rs:22:22
     |
  17 | fn generate&lt;'a, TF, TC, TS&gt;(config: &amp;TF)
     |             -- lifetime `'a` defined here
  ...
  22 |     let mut source = connection.data_source();
     |                      ^^^^^^^^^^--------------
     |                      |
     |                      borrowed value does not live long enough
     |                      argument requires that `connection` is borrowed for `'a`
  23 |     println!("{:?}", source.get_data());
  24 | }
     | - `connection` dropped here while still borrowed
  </code></pre>
  
  <p>How can I describe that <code>connection</code> overlives <code>source</code>? My attempts introducing a scope around <code>source</code> or a <code>'b: 'a</code> for <code>connection</code> did not give positive results.</p>
  
  <h1>Another try with <code>Box</code> and associated types</h1>
  
  <p>After some comments by Ömer Erden and Kornel I tried boxing the traits and using associated types. <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=663b0f8c86e2e46c408e3ffd16958c91" rel="nofollow noreferrer">Woohoow, it compiles!</a>:</p>
  
  <pre class="lang-rust prettyprint-override"><code>#![feature(generic_associated_types)]
  trait DataSource {
      fn get_data(&amp;mut self) -&gt; String;
      fn transaction(&amp;mut self) -&gt; postgres::Transaction&lt;'_&gt; { unimplemented!() }
  }
  trait BackendConnection {
      type Source&lt;'a&gt;;
      fn data_source(&amp;mut self) -&gt; Self::Source&lt;'_&gt;;
  }
  trait BackendConfiguration {
      type Connection;
      fn connect(&amp;self) -&gt; Self::Connection;
  }
  
  fn generate&lt;TF&gt;(config: &amp;TF)
  where
      TF: BackendConfiguration&lt;Connection=Box&lt;dyn BackendConnection&lt;Source=Box&lt;dyn DataSource&gt;&gt;&gt;&gt;
  {
      let mut connection = config.connect();
      let mut source = connection.data_source();
      println!("{:?}", source.get_data());
  }
  
  // You can ignore all this, it is there just to show the reason why
  // the lifetime is needed in `data_source(&amp;'a mut self)` above.
  
  mod pg {
      pub struct PgSource&lt;'a&gt; {transaction: postgres::Transaction&lt;'a&gt;}
      impl super::DataSource for PgSource&lt;'_&gt; {
          fn get_data(&amp;mut self) -&gt; String {
              let mut data = String::new();
              for row in self.transaction.query("SELECT CURRENT_TIMESTAMP", &amp;[]).unwrap() {
                  let st: std::time::SystemTime = row.get(0);
                  data.push_str(&amp;format!("{:?}\n", st));
              }
              data
          }
          fn transaction(&amp;mut self) -&gt; postgres::Transaction&lt;'_&gt; {
              self.transaction.transaction().unwrap()
          }
      }
  
      pub struct PgConnection {client: postgres::Client}
      impl super::BackendConnection for PgConnection {
          type Source&lt;'a&gt; = Box&lt;PgSource&lt;'a&gt;&gt;;
          fn data_source(&amp;mut self) -&gt; Self::Source&lt;'_&gt; {
              let transaction = self.client.transaction().unwrap();
              Box::new(PgSource { transaction })
          }
      }
  
      pub struct PgConfiguration {config: postgres::Config}
      impl PgConfiguration {
          pub fn new(params: &amp;str) -&gt; Self {
              let config = params.parse::&lt;postgres::Config&gt;().unwrap();
              Self { config }
          }
      }
      impl super::BackendConfiguration for PgConfiguration {
          type Connection = Box&lt;PgConnection&gt;;
          fn connect(&amp;self) -&gt; Self::Connection {
              let client = self.config.connect(postgres::tls::NoTls).unwrap();
              Box::new(PgConnection { client })
          }
      }
  }
  </code></pre>
  
  <p>But it still <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=045d443bee9cbc48cbb2988fa767a8c5" rel="nofollow noreferrer">fails to compile when I use the generic</a>:</p>
  
  <pre class="lang-rust prettyprint-override"><code>fn main() {
      let cfg = pg::PgConfiguration::new("host=host.example user=myself");
      generate(&amp;cfg);
  }
  </code></pre>
  
  <p>The error is:</p>
  
  <pre><code>error[E0271]: type mismatch resolving `&lt;pg::PgConfiguration as BackendConfiguration&gt;::Connection == std::boxed::Box&lt;(dyn BackendConnection&lt;Source = std::boxed::Box&lt;(dyn DataSource + 'static)&gt;&gt; + 'static)&gt;`
    --&gt; src/lib.rs:26:5
     |
  15 | fn generate&lt;TF&gt;(config: &amp;TF)
     |    --------
  16 | where
  17 |     TF: BackendConfiguration&lt;Connection=Box&lt;dyn BackendConnection&lt;Source=Box&lt;dyn DataSource&gt;&gt;&gt;&gt;
     |                              ----------------------------------------------------------------- required by this bound in `generate`
  ...
  26 |     generate(&amp;cfg);
     |     ^^^^^^^^ expected trait object `dyn BackendConnection`, found struct `pg::PgConnection`
     |
     = note: expected struct `std::boxed::Box&lt;(dyn BackendConnection&lt;Source = std::boxed::Box&lt;(dyn DataSource + 'static)&gt;&gt; + 'static)&gt;`
                found struct `std::boxed::Box&lt;pg::PgConnection&gt;`
  
  error: aborting due to previous error
  
  For more information about this error, try `rustc --explain E0271`.
  </code></pre>
  
  <h1>Note</h1>
  
  <p>If I <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=00aba7a0a827b5bbeec46666af1b8e63" rel="nofollow noreferrer">monomorphize <code>generate</code> by hand it works</a>:</p>
  
  <pre class="lang-rust prettyprint-override"><code>fn generate_for_pg(config: &amp;pg::PgConfiguration) {
      let mut connection = config.connect();
      let mut source = connection.data_source();
      println!("{:?}", source.get_data());
  }
  </code></pre>
  
  <p>But of course I want to avoid this because it creates code duplication (I'd have to write a <code>generate_for_oracle</code>).</p>