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 <illiss...@gmail.com> wrote:

>
> `On Sun, Sep 29, 2013 at 9:21 PM, Oren Ben-Kiki <o...@ben-kiki.org> 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 <illiss...@gmail.com> 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 <o...@ben-kiki.org>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 <dwrens...@gmail.com>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
>>>>> 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
>>>>
>>>>
>>>
>>>
>>> --
>>> Your ship was destroyed in a monadic eruption.
>>>
>>
>>
>
>
> --
> Your ship was destroyed in a monadic eruption.
>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to