Could you use struct methods for "quick access"? Or is there a reason this
wouldn't fit your use case? Sorry, I haven't followed the whole thread
closely.

struct Owner {
    owned: ~[int],
}

impl Owner {
    fn quick_access<'a>(&'a mut self) -> &'a mut int {
        &mut self.owned[0]
    }
}


On Sun, Sep 29, 2013 at 5:32 PM, Oren Ben-Kiki <[email protected]> wrote:

> That's... surprising. Even ignoring the fact the name "self" means exactly
> the opposite (déjà vu from "const" here)...
>
> I don't suppose there's a chance that something like what I expected 'self
> to be like would be supported at some point? Its lack rules out a lot of
> reasonable, safe, useful code.
>
>
>
> On Mon, Sep 30, 2013 at 12:13 AM, Gábor Lehel <[email protected]> wrote:
>
>>
>> `On Sun, Sep 29, 2013 at 9:21 PM, Oren Ben-Kiki <[email protected]>wrote:
>>
>>> Thanks for the explanation. You said two key points:
>>> - Basically, every object has a lifetime - from its creation to its
>>> destruction - but a lifetime parameter or argument typically refers to the
>>> lifetime of something else, which the object itself must not or does not
>>> outlive.
>>> And:
>>> - 'self is not special in any way, except that the compiler has
>>> historical baggage such that 'self is the only name it lets you use for a
>>> lifetime parameter on a struct.
>>>
>>> So, 'self is indeed very far from what I thought (hoped) it would be.
>>>
>>> Taking these together, do I read this right as saying there is no way
>>> whatsoever to say:
>>>
>>> struct Foo {
>>>     bar: Bar,
>>>     baz: &'i-live-as-long-as-the-foo-struct-and-no-more BazPartOfBar,
>>> }
>>>
>>
>> Per my understanding, this is correct. Because there is a constraint on
>> the lifetime of a part of `Foo`, there must a constraint on the lifetime of
>> `Foo`. It has to propagate outwards to make sure the lifetime of the whole
>> structure is properly constrained. You basically want to "propagate
>> inwards". I don't think that's possible, but maybe someone will correct me.
>>
>>
>>>
>>> When writing a non-trivial container, I found several user cases to be
>>> extremely problematic. One was the above; a container held a "spine" or
>>> "master" or "owned" or whatever-you-want-to-call-it data structure(s), plus
>>> borrowed pointers that only live as long as the container and allow quick
>>> access to specific parts of it.
>>>
>>> Is this impossible in Rust (barring use of @ or unsafe pointers)?
>>>
>>
>> This sounds similar to the case of a doubly linked list (with forward
>> pointers being the "spine" and backwards the "quick access"), which is  not
>> possible as an 'owned' structure as far as I know without unsafe pointers.
>>
>>
>>>
>>>
>>> On Sun, Sep 29, 2013 at 8:24 PM, Gábor Lehel <[email protected]>wrote:
>>>
>>>> 'self is not special in any way, except that the compiler has
>>>> historical baggage such that 'self is the only name it lets you use for a
>>>> lifetime parameter on a struct. But that's a bug. In the ideal platonic
>>>> Rust in the sky, you can have any number of lifetime parameters on a struct
>>>> with whatever names you prefer.
>>>>
>>>> The way I've found to think about lifetimes is that if you have:
>>>>
>>>> r_int: &'a int
>>>>
>>>> then 'a refers to a span of time (a scope, a lifetime) such that
>>>> lifetime_of(r_int) <= 'a <= lifetime_of(*r_int). (Where *r_int is intended
>>>> metaphorically to refer to the original object r_int was created from, not
>>>> the result of the *r_int expression itself.) So 'a is a kind of stand
>>>> between to ensure that r_int does not outlive the object it refers to.
>>>>
>>>> If you have
>>>>
>>>> fn foo<'a>(r_int: &'a int) -> &'a int
>>>>
>>>> then just like any other generics argument, the lifetime 'a is chosen
>>>> by the caller of `foo` (as inferred by the compiler). Typically the caller
>>>> will have an int object (i: int), then borrow a reference to it (r_int: &'a
>>>> int = &i) which it passes to `foo`, and then 'a will be the lifetime of the
>>>> int. `foo` will then have to return a reference to (an int that lives at
>>>> least as long). In practice this could either be the r_int it got as
>>>> argument, or a static int.
>>>>
>>>> `fn foo(arg: &int)` is shorthand for an anonymous lifetime parameter:
>>>> `fn foo<'a>(arg: &'a int)`
>>>>
>>>> In the return type position `fn foo() -> &int` is short for
>>>> `fn foo<'a>() -> &'a int`, meaning `foo` has to return a reference to (an
>>>> int that lives as long as any lifetime the caller could choose), which in
>>>> practice means that it has to be 'static. I believe you are or will be
>>>> required to write &'static explicitly in these cases to avoid confusion.
>>>>
>>>> With a struct it's not much different.
>>>>
>>>> s: MyStruct<'a> means lifetime_of(s) <= 'a
>>>> s: MyStruct<'a, 'b> means lifetime_of(s) <= 'a && lifetime_of(s) <= 'b
>>>>
>>>> If you have
>>>>
>>>> struct MyStruct<'self> {
>>>>     r_int: &'self int
>>>> }
>>>>
>>>> s: MyStruct<'a>
>>>>
>>>> then lifetime_of(s) <= 'a && lifetime_of(s.r_int) <= 'a. (Which is
>>>> trivial because lifetime_of(s) == lifetime_of(s.r_int).)
>>>>
>>>> Basically, every object has a lifetime - from its creation to its
>>>> destruction - but a lifetime parameter or argument typically refers to the
>>>> lifetime of something else, which the object itself must not or does not
>>>> outlive.
>>>>
>>>> (Please yell at me if I got any of this wrong.)
>>>>
>>>>
>>>>
>>>> On Sun, Sep 29, 2013 at 5:23 PM, Oren Ben-Kiki <[email protected]>wrote:
>>>>
>>>>> Ok, color me confused... perhaps there's somewhere that explains 'self
>>>>> on more detail? For example, _why_ does the example below not work without
>>>>> the explicit <'self>? It seems like it should.
>>>>>
>>>>> I have yet to truly understand the whole 'self thing. When I first
>>>>> read about lifetimes, my naive expectations were that:
>>>>>
>>>>> - Every struct has a 'self lifetime, which is basically "as long as
>>>>> this struct exists". It doesn't matter if I have a @ of the struct or a ~
>>>>> of the struct or just a local variable with the struct... when the struct
>>>>> is dropped, the lifetime ends.
>>>>>
>>>>> - It follows there's no need to ever annotate structs as generic with
>>>>> a <'self> parameter - it always exists.
>>>>>
>>>>> - Any & in a struct is either &'self or &'static. A simple & should be
>>>>> &'self as that makes more sense (but if Rust wants me to be explicit, 
>>>>> fine).
>>>>>
>>>>> This were my "least surprise" expectations, but things don't work this
>>>>> way... the problem is I don't have a simple mental model to replace the
>>>>> above with, so I struggle. What _is_ 'self, exactly?
>>>>>
>>>>> Isn't a function fn foo(&self) -> &T the same as returning a &'self T?
>>>>> Why would I want to say fn foo<'a>(&'a self) in the 1st place - 'a is "by
>>>>> definition" the same as 'self? How come David's Foo example fails the
>>>>> borrow check?
>>>>>
>>>>> Besides failing (my) "least surprise" expectations, the current rules
>>>>> also seem to be a "leaky abstraction". If I have a struct that holds a
>>>>> ComplexT member, it needs no <'self> parameter. If I then add a private
>>>>> member to my struct to hold some &'self PartOfT (say, cached access to an
>>>>> internal member), then boom, all uses of my struct now have to say 
>>>>> <'self>,
>>>>> I can no longer put it in thread-local-storage, etc. I'd expect keeping
>>>>> these sort of cached borrowed pointers should be an internal 
>>>>> implementation
>>>>> detail which does not affect the users of the struct at all.
>>>>>
>>>>> I suppose there's a good reason for all this, and a reasonable mental
>>>>> model I need to put in my head, but digging around the docs I didn't find
>>>>> one... Any hints would be appreciated :-)
>>>>>
>>>>>
>>>>> On Sun, Sep 29, 2013 at 5:42 PM, David Renshaw <[email protected]>wrote:
>>>>>
>>>>>> Cool! I think that solution is much better than mine.
>>>>>>
>>>>>> > But I
>>>>>> > think that polluting traits-interfaces with lifetime annotation is
>>>>>> > wrong. Why the trait should have lifetime annotation? It is
>>>>>> > implementation detail.
>>>>>>
>>>>>> Just in case you want to see a case where it *does* make sense to put
>>>>>> a 'self lifetime in a trait definition, here is an example:
>>>>>>
>>>>>> https://gist.github.com/dwrensha/db919b8e130e9eb72f0f
>>>>>> _______________________________________________
>>>>>> Rust-dev mailing list
>>>>>> [email protected]
>>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Rust-dev mailing list
>>>>> [email protected]
>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Your ship was destroyed in a monadic eruption.
>>>>
>>>
>>>
>>
>>
>> --
>> Your ship was destroyed in a monadic eruption.
>>
>
>
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
>
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to