1

I want to pass a reference to a Rusoto SQS client to a WebSocket server struct to push messages onto an SQS queue.

To that end, I have a (naive) struct as follows:

struct MyHandler {
    sqsclient: &SqsClient<ProvideAwsCredentials, DispatchSignedRequest>,
}

This produces the error:

error[E0106]: missing lifetime specifier
  --> src/main.rs:29:13
   |
29 |    sqsclient: &SqsClient<ProvideAwsCredentials, DispatchSignedRequest>,
   |               ^ expected lifetime parameter

I've attempted all sorts of type signatures and lifetime trickery which all fail to varying levels, but I keep coming up against the same error:

error[E0277]: the trait bound `rusoto_core::ProvideAwsCredentials + 'static: std::marker::Sized` is not satisfied
  --> src/main.rs:29:2
   |
29 |    sqsclient: &'static SqsClient<ProvideAwsCredentials, DispatchSignedRequest>,
   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `rusoto_core::ProvideAwsCredentials + 'static` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `rusoto_core::ProvideAwsCredentials + 'static`
   = note: required by `rusoto_sqs::SqsClient`

error[E0277]: the trait bound `rusoto_core::DispatchSignedRequest + 'static: std::marker::Sized` is not satisfied
  --> src/main.rs:29:2
   |
29 |    sqsclient: &'static SqsClient<ProvideAwsCredentials, DispatchSignedRequest>,
   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `rusoto_core::DispatchSignedRequest + 'static` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `rusoto_core::DispatchSignedRequest + 'static`
   = note: required by `rusoto_sqs::SqsClient`

I've also tried wrapping it in Rc and Box to no avail. I feel like I'm looking in the wrong place with these though.

This happens when giving MyHandler an <'a> lifetime too. What am I misunderstanding about the Rust type system here, and what can I do to be able to pass a reference to an SqsClient<...> (and eventually other stuff from Rusoto) into my own structs? It would be useful to know if what I'm trying to do above is idiomatic Rust. If it's not, what pattern should I use instead?

This is a follow up from How do I pass a struct with type parameters as a function argument?.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Bojangles
  • 99,427
  • 50
  • 170
  • 208

1 Answers1

2

Solved it! DispatchSignedRequest and ProvideAwsCredentials (from Rusoto) are traits. I needed to use impls of those traits, i.e. structs, so now the code looks like this:

extern crate rusoto_core;
extern crate hyper;

use hyper::Client;
use rusoto_sqs::{ Sqs, SqsClient };
use rusoto_core::{ DefaultCredentialsProvider };

struct MyHandler<'a> {
    sqsclient: &'a SqsClient<DefaultCredentialsProvider, Client>,
}

impl<'a> Handler for MyHandler<'a> {
    // ...
}

DefaultCredentialsProvider and Client (from Hyper) are both structs, so now this code compiles fine.

I'm using Hyper 0.10 here. Hyper 0.11 requires a different type signature for Client.

Bojangles
  • 99,427
  • 50
  • 170
  • 208