Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'static lifetimes in operations #102

Open
AlexNav73 opened this issue Feb 9, 2017 · 2 comments
Open

'static lifetimes in operations #102

AlexNav73 opened this issue Feb 9, 2017 · 2 comments

Comments

@AlexNav73
Copy link

Hi, in my case, i need to use &'static str for index and doc type, but lifetimes in IndexOperation in such case, disallow me pass reference to doc with non-static lifetime. What i try to say:

const ES_INDEX_NAME: &'static str = "my_index";

pub trait EsDocument: Serialize + Deserialize {
    fn entity_type() -> &'static str;
}

pub fn index<'a, 'b, T>(&'a mut self, doc: &'b T) -> &'a mut IndexOperation<'a, 'b, T> 
    where T: EsDocument
{
    self.client.index(ES_INDEX_NAME, T::entity_type()).with_doc(doc)
}

In this example, lifetime 'b == 'static, because:

fn index<'a, 'b, E: Serialize>(&'a mut self, index: &'b str, doc_type: &'b str) -> IndexOperation<'a, 'b, E>
fn with_doc(&'b mut self, doc: &'b E) -> &'b mut Self

with_doc accepts &'b E (in our case &'static E) and passing doc: &'b T for 'b != 'static breaks borrow checker rules

For now, possible solution can be using mem::transmute to avoid this lifetime rules.

@benashford benashford added bug and removed bug labels Feb 10, 2017
@benashford
Copy link
Owner

Thanks for the notification.

Do you have a larger example that demonstrates the problem? Perhaps something I can encapsulate in a test case?

In a simple case, using something like:

const INDEX_NAME: &'static str = "my_index";

fn test() {
   let mut client = create_client();
   client.index(INDEX_NAME, "type").with_doc(&make_document()).send();
}

works as you'd expect, because the lifetime is self-contained and all the parameters exceed what's required. But in your case you're returning the IndexOperation.

I expect the solution will be the same in all cases, but it would be good to have a reproducible test or example code to verify it.

@AlexNav73
Copy link
Author

AlexNav73 commented Feb 12, 2017

Here is example of code:

extern crate rs_es;
extern crate serde;

use rs_es::Client;
use rs_es::operations::index::IndexOperation;
use serde::Serialize;

const INDEX_NAME: &'static str = "my_index";

struct Wrapper(Client);

impl Wrapper {
    fn get_index_operation<'a, 'b, T: Serialize>(&self, doc: &'b T) -> &'a mut IndexOperation<'a, 'b, T> {
        self.0.index(INDEX_NAME, "type").with_doc(doc)
    }
}

fn main() { }

How can i set lifetimes to make it compile? Now it says:

main.rs|15 col 16 error 495| cannot infer an appropriate lifetime for autoref due to conflicting requirements
||    |
|| 15 |         self.0.index(INDEX_NAME, "type").with_doc(doc)
||    |                ^^^^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants