Sami Nopanen wrote:
1. Why is the lifetime name sometimes before a type and sometimes after the type.

There are two kinds of types which can be annotated with lifetime names. The first is a borrowed pointer:

&lt/T

In this case, the lifetime `lt` is the lifetime of this pointer. The second is a struct, enum, or type alias:

    StringReader/&lt

In this case, the lifetime `lt` is the lifetime of any borrowed pointers contained within the struct, enum, or type alias. So, in the case of the `StringReader` example you gave, the definition of `StringReader` was:

  struct StringReader { value: &str, count: uint }

Therefore, `StringReader/&lt` means "a StringReader where the lifetime of the `value` field is `lt`". The definition of StringReader is really a kind of generic type definition parameterized over a lifetime, kind of like:

    struct StringReader<&lt> {
        value: &lt/str,
        count: uint
    }

Right now the compiler hides this declaration from you to make things more pleasant and easy to type. However, we have all agreed on changing this so that lifetime parameters on structs, enums, etc will become explicit. But there are some niggling details remaining as to the precise syntax.

2. In the 'new' method, is the 'self' in the parameter 'value: &self/str' just a random name for the lifetime parameter or does this refer somehow to the 'self' type (in which case I'd be ever
   more confused, I guess :-):

The `self` is a lifetime in that instance. I mentioned before that (today) the compiler implicitly decides when a type is parameterized by a lifetime. When it does, it uses the name `self` as the name of the lifetime parameter. So the `self` lifetime here refers to the lifetime of the borrowed pointers contained within the `self` struct.

As far as I understand, this would mean that the type instance would have to be built in the same stack frame as where the variable binding defining the lifetime parameter precides.
This is close but not quite right. It's not actually important where the newly constructed struct is stored. It's only important when it gets used. So if the struct is built with a string with lifetime X, then we must make sure that the struct is not used outside of that lifetime X.

But how about if the string has a lifetime beyond the calling function, such as:
     fn foo(s : &str) {
       let sr = StringReader::new(s);
       ...
       sr
     }
     fn bar() {
       let s = ~"foobar";
       let sr = foo(s);
     }

This example can be typed, but it requires some annotations. In particular, `foo` should look like:

     fn foo(s : &v/str) -> StringReader/&v {
       let sr = StringReader::new(s);
       ...
       sr
     }

Here, the return type `StringReader/&v` tells the caller of `foo()`: "I am going to be returning a StringReader that is valid for the same lifetime as the string `s` that you gave me."

If you did not supply the explicit lifetime annotation, you will get a compile-time error, because the caller does not know that there is a link between the lifetime of `s` and the lifetime of the returned value. In general, whenever you return a borrowed pointer, or a value that contains borrowed pointers, you will need an explicit lifetime annotation so that you can link the lifetime of that return value to the lifetime of a parameter.

Now, for the lifetime of StringReader to match the lifetime of the string, it AFAIK would need to be stored in the stack frame of 'bar' instead of the stackframe of 'foo'. Does this actually happen (e.g. the compiler is able to preallocate the correct slots in the stack), is there some other magic going on or
   would this just be a compile error?

As I wrote above, there is less magic going on then you think. The `StringReader` will initially be stored in the stack frame of `foo` and then copied into the stack frame of `bar()` when `foo()` returns. It's not required that it only be stored in `bar()`, so long as it is never used after `bar()` returns.

Hope this helps.



regards,

Niko

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to