If I'm interpreting this right, you also need to add a second lifetime 
parameter to your ResultSet object. This way the lifetime used for its 
reference to the Statement can be different than the lifetime on the Statement 
type itself (I assume Statement has a lifetime to refer to the database).

I whipped up an equivalent bit of code. The following reproduces your error:

struct Root {
    s: String
}

struct One<'a> {
    root: &'a mut Root
}

struct Two<'a> {
    one: &'a mut One<'a>
}

impl Root {
    pub fn make_one<'a>(&'a mut self) -> One<'a> {
        One { root: self }
    }
}

impl<'a> One<'a> {
    pub fn make_two(&'a mut self) -> Two<'a> {
        Two { one: self }
    }

    pub fn foo(&mut self) {
        println!("foo");
    }
}

fn main() {
    let mut r = Root { s: "root".to_string() };
    let mut one = r.make_one();
    match one.make_two() {
        x => {
            println!("root: {}", x.one.root.s);
        }
    }

    one.foo();
}
The equivalent change here that I'm proposing is updating Two to

struct Two<'a, 'b> {
    one: &'b mut One<'a>
}
and the definition of make_two() to

    pub fn make_two<'b>(&'b mut self) -> Two<'a, 'b> {
        Two { one: self }
    }

-Kevin

On May 30, 2014, at 3:12 PM, Kevin Ballard <ke...@sb.org> wrote:

> I'm assuming that Statement has its own lifetime parameter? And that's the 'a 
> you're using here?
> 
> Try using a new lifetime.
> 
> pub fn execute_query<'b>(&'b mut self) -> ResultSelf<'b>;
> 
> -Kevin
> 
> On May 30, 2014, at 1:54 AM, Christophe Pedretti 
> <christophe.pedre...@gmail.com> wrote:
> 
>> Hi All,
>> 
>> sorry for my late replay, i am UTC+2
>> 
>> > Won't wrapping the first `for` loop into curly braces help?
>> no
>> 
>> > is this a database library you're writing yourself?
>> yes
>> 
>> > My best guess here is that you've accidentally used the wrong lifetime on
>> > your `execute_query()` method, tying the lifetime of the `self` reference 
>> > to
>> > a lifetime on the value itself
>> 
>> yes, but removing the lifetime reference on the self, compiling my library 
>> gives
>> 
>> sql\connection.rs:57:2: 64:3 note: consider using an explicit lifetime 
>> parameter as shown: fn execute_query(&'a mut self) -> ResultSet<'a>
>> sql\connection.rs:57    pub fn execute_query(&mut self) -> ResultSet<'a> {
>> sql\connection.rs:58            match self.pCon.dbType {
>> sql\connection.rs:59            SQLITE3 => {
>> sql\connection.rs:60            if self.exec { unsafe { 
>> sqlite3_reset(self.pStmt) }; } else {self.exec=true; }
>> sql\connection.rs:61            ResultSet { pStmt : self, error : false }
>> sql\connection.rs:62            }
>>                      ...
>> sql\connection.rs:61:23: 61:27 error: cannot infer an appropriate lifetime 
>> for automatic coercion due to conflicting requirements
>> sql\connection.rs:61            ResultSet { pStmt : self, error : false }
>>                                                     ^~~~
>> 
>> execute_query can be used only for the loop body, and if there is no 
>> variable referencing it there is no reason for the execute-query to live 
>> outside the loop (as is my example)
>> 
>> or, with code like this :
>> 
>> let query_result = st.execute_query()
>> for i in query_result {
>> ...
>> 
>> and in this case, the query_result lives outside the loop
>> 
>> the compiler can not distinguish these two usages ?
>> 
>> Thanks
>> 
>> 2014-05-30 9:17 GMT+02:00 Kevin Ballard <ke...@sb.org>:
>> On May 30, 2014, at 12:12 AM, Vladimir Matveev <dpx.infin...@gmail.com> 
>> wrote:
>> 
>> > 2014-05-30 5:37 GMT+04:00 Kevin Ballard <ke...@sb.org>:
>> >>
>> >> It shouldn't.
>> >>
>> >> The for-loop desugaring looks like
>> >>
>> >> match &mut st.execute_query() {
>> >>    __i => loop {
>> >>        match __i.next() {
>> >>            None => break,
>> >>            Some(mut __value) => {
>> >>                let i = __value;
>> >>                {
>> >>                    // for loop body goes here
>> >>                }
>> >>            }
>> >>        }
>> >>    }
>> >> }
>> >>
>> >> It's done with a match statement like this specifically to make the &mut 
>> >> binding of the iterator end after the for loop.
>> >
>> > Great, didn't know it. Last time I asked (on StackOverflow, I think;
>> > that was some time ago though) there were no `match`. Then from that
>> > code alone it does look like a bug to me. Note that it refers to
>> > `st.set_string("%e%")` and `for` loop ten lines above, that is, the
>> > first one. If mutable borrow of the iterator aren't escaping the loop,
>> > then this error should not appear, right?
>> 
>> The errors you printed are slightly malformed, and you only listed some of 
>> your code. Is this a database library you're writing yourself? My best guess 
>> here is that you've accidentally used the wrong lifetime on your 
>> `execute_query()` method, tying the lifetime of the `self` reference to a 
>> lifetime on the value itself. Something like this:
>> 
>> impl<'a> Statement<'a> {
>>     pub fn execute_query(&'a mut self) { ... }
>> }
>> 
>> By using 'a on &'a mut self here, you've explicitly tied the reference to 
>> the lifetime of the value. This causes the mutable reference to live much 
>> longer than you expected it to, which means it's still alive when you try to 
>> subsequently borrow it on your call to .set_string().
>> 
>> -Kevin
>> 
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
> 
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to