'borrowed pointer' -> 'reference'
This commit is contained in:
parent
b65b4d6384
commit
d323632669
39 changed files with 185 additions and 186 deletions
|
@ -218,13 +218,13 @@ They start small (ideally in the hundreds of bytes) and expand dynamically by ca
|
|||
* Managed boxes may not be shared between tasks
|
||||
* Owned boxes may be transferred (moved) between tasks
|
||||
|
||||
## What is the difference between a borrowed pointer (`&`) and managed and owned boxes?
|
||||
## What is the difference between a reference (`&`) and managed and owned boxes?
|
||||
|
||||
* Borrowed pointers point to the interior of a stack _or_ heap allocation
|
||||
* Borrowed pointers can only be formed when it will provably be outlived by the referent
|
||||
* Borrowed pointers to managed box pointers keep the managed boxes alive
|
||||
* Borrowed pointers to owned boxes prevent their ownership from being transferred
|
||||
* Borrowed pointers employ region-based alias analysis to ensure correctness
|
||||
* References point to the interior of a stack _or_ heap allocation
|
||||
* References can only be formed when it will provably be outlived by the referent
|
||||
* References to managed box pointers keep the managed boxes alive
|
||||
* References to owned boxes prevent their ownership from being transferred
|
||||
* References employ region-based alias analysis to ensure correctness
|
||||
|
||||
## Why aren't function signatures inferred? Why only local slots?
|
||||
|
||||
|
|
|
@ -417,7 +417,7 @@ However, there are currently no guarantees about the layout of an `enum`.
|
|||
|
||||
Rust's owned and managed boxes use non-nullable pointers as handles which point to the contained
|
||||
object. However, they should not be manually created because they are managed by internal
|
||||
allocators. Borrowed pointers can safely be assumed to be non-nullable pointers directly to the
|
||||
allocators. References can safely be assumed to be non-nullable pointers directly to the
|
||||
type. However, breaking the borrow checking or mutability rules is not guaranteed to be safe, so
|
||||
prefer using raw pointers (`*`) if that's needed because the compiler can't make as many assumptions
|
||||
about them.
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
% The Rust Borrowed Pointers and Lifetimes Guide
|
||||
% The Rust References and Lifetimes Guide
|
||||
|
||||
# Introduction
|
||||
|
||||
Borrowed pointers are one of the more flexible and powerful tools available in
|
||||
Rust. A borrowed pointer can point anywhere: into the managed or exchange
|
||||
References are one of the more flexible and powerful tools available in
|
||||
Rust. A reference can point anywhere: into the managed or exchange
|
||||
heap, into the stack, and even into the interior of another data structure. A
|
||||
borrowed pointer is as flexible as a C pointer or C++ reference. However,
|
||||
reference is as flexible as a C pointer or C++ reference. However,
|
||||
unlike C and C++ compilers, the Rust compiler includes special static checks
|
||||
that ensure that programs use borrowed pointers safely. Another advantage of
|
||||
borrowed pointers is that they are invisible to the garbage collector, so
|
||||
working with borrowed pointers helps reduce the overhead of automatic memory
|
||||
that ensure that programs use references safely. Another advantage of
|
||||
references is that they are invisible to the garbage collector, so
|
||||
working with references helps reduce the overhead of automatic memory
|
||||
management.
|
||||
|
||||
Despite their complete safety, a borrowed pointer's representation at runtime
|
||||
Despite their complete safety, a reference's representation at runtime
|
||||
is the same as that of an ordinary pointer in a C program. They introduce zero
|
||||
overhead. The compiler does all safety checks at compile time.
|
||||
|
||||
Although borrowed pointers have rather elaborate theoretical
|
||||
Although references have rather elaborate theoretical
|
||||
underpinnings (region pointers), the core concepts will be familiar to
|
||||
anyone who has worked with C or C++. Therefore, the best way to explain
|
||||
how they are used—and their limitations—is probably just to work
|
||||
|
@ -24,8 +24,8 @@ through several examples.
|
|||
|
||||
# By example
|
||||
|
||||
Borrowed pointers are called *borrowed* because they are only valid for
|
||||
a limited duration. Borrowed pointers never claim any kind of ownership
|
||||
References, sometimes known as *borrowed pointers*, are only valid for
|
||||
a limited duration. References never claim any kind of ownership
|
||||
over the data that they point to: instead, they are used for cases
|
||||
where you would like to use data for a short time.
|
||||
|
||||
|
@ -55,7 +55,7 @@ define it this way, calling the function will cause the points to be
|
|||
copied. For points, this is probably not so bad, but often copies are
|
||||
expensive. Worse, if the data type contains mutable fields, copying can change
|
||||
the semantics of your program in unexpected ways. So we'd like to define a
|
||||
function that takes the points by pointer. We can use borrowed pointers to do
|
||||
function that takes the points by pointer. We can use references to do
|
||||
this:
|
||||
|
||||
~~~
|
||||
|
@ -89,7 +89,7 @@ name for the same data.
|
|||
|
||||
In contrast, we can pass the boxes `managed_box` and `owned_box` to
|
||||
`compute_distance` directly. The compiler automatically converts a box like
|
||||
`@Point` or `~Point` to a borrowed pointer like `&Point`. This is another form
|
||||
`@Point` or `~Point` to a reference like `&Point`. This is another form
|
||||
of borrowing: in this case, the caller lends the contents of the managed or
|
||||
owned box to the callee.
|
||||
|
||||
|
@ -100,7 +100,7 @@ addition, the compiler will reject any code that might cause the borrowed
|
|||
value to be freed or overwrite its component fields with values of different
|
||||
types (I'll get into what kinds of actions those are shortly). This rule
|
||||
should make intuitive sense: you must wait for a borrower to return the value
|
||||
that you lent it (that is, wait for the borrowed pointer to go out of scope)
|
||||
that you lent it (that is, wait for the reference to go out of scope)
|
||||
before you can make full use of it again.
|
||||
|
||||
# Other uses for the & operator
|
||||
|
@ -114,7 +114,7 @@ let on_the_stack: Point = Point {x: 3.0, y: 4.0};
|
|||
|
||||
This declaration means that code can only pass `Point` by value to other
|
||||
functions. As a consequence, we had to explicitly take the address of
|
||||
`on_the_stack` to get a borrowed pointer. Sometimes however it is more
|
||||
`on_the_stack` to get a reference. Sometimes however it is more
|
||||
convenient to move the & operator into the definition of `on_the_stack`:
|
||||
|
||||
~~~
|
||||
|
@ -180,7 +180,7 @@ as well as from the managed box, and then compute the distance between them.
|
|||
|
||||
We’ve seen a few examples so far of borrowing heap boxes, both managed
|
||||
and owned. Up till this point, we’ve glossed over issues of
|
||||
safety. As stated in the introduction, at runtime a borrowed pointer
|
||||
safety. As stated in the introduction, at runtime a reference
|
||||
is simply a pointer, nothing more. Therefore, avoiding C's problems
|
||||
with dangling pointers requires a compile-time safety check.
|
||||
|
||||
|
@ -195,7 +195,7 @@ broader scope than the pointer itself), the compiler reports an
|
|||
error. We'll be discussing lifetimes more in the examples to come, and
|
||||
a more thorough introduction is also available.
|
||||
|
||||
When the `&` operator creates a borrowed pointer, the compiler must
|
||||
When the `&` operator creates a reference, the compiler must
|
||||
ensure that the pointer remains valid for its entire
|
||||
lifetime. Sometimes this is relatively easy, such as when taking the
|
||||
address of a local variable or a field that is stored on the stack:
|
||||
|
@ -209,7 +209,7 @@ fn example1() {
|
|||
} // -+
|
||||
~~~
|
||||
|
||||
Here, the lifetime of the borrowed pointer `y` is simply L, the
|
||||
Here, the lifetime of the reference `y` is simply L, the
|
||||
remainder of the function body. The compiler need not do any other
|
||||
work to prove that code will not free `x.f`. This is true even if the
|
||||
code mutates `x`.
|
||||
|
@ -384,7 +384,7 @@ enum Shape {
|
|||
~~~
|
||||
|
||||
Now we might write a function to compute the area of a shape. This
|
||||
function takes a borrowed pointer to a shape, to avoid the need for
|
||||
function takes a reference to a shape, to avoid the need for
|
||||
copying.
|
||||
|
||||
~~~
|
||||
|
@ -466,19 +466,19 @@ same rules as the ones we saw for borrowing the interior of a owned
|
|||
box: it must be able to guarantee that the `enum` will not be
|
||||
overwritten for the duration of the borrow. In fact, the compiler
|
||||
would accept the example we gave earlier. The example is safe because
|
||||
the shape pointer has type `&Shape`, which means "borrowed pointer to
|
||||
the shape pointer has type `&Shape`, which means "reference to
|
||||
immutable memory containing a `shape`". If, however, the type of that
|
||||
pointer were `&mut Shape`, then the ref binding would be ill-typed.
|
||||
Just as with owned boxes, the compiler will permit `ref` bindings
|
||||
into data owned by the stack frame even if the data are mutable,
|
||||
but otherwise it requires that the data reside in immutable memory.
|
||||
|
||||
# Returning borrowed pointers
|
||||
# Returning references
|
||||
|
||||
So far, all of the examples we have looked at, use borrowed pointers in a
|
||||
So far, all of the examples we have looked at, use references in a
|
||||
“downward” direction. That is, a method or code block creates a
|
||||
borrowed pointer, then uses it within the same scope. It is also
|
||||
possible to return borrowed pointers as the result of a function, but
|
||||
reference, then uses it within the same scope. It is also
|
||||
possible to return references as the result of a function, but
|
||||
as we'll see, doing so requires some explicit annotation.
|
||||
|
||||
For example, we could write a subroutine like this:
|
||||
|
@ -496,7 +496,7 @@ explicitly. So in effect, this function declares that it takes a
|
|||
pointer with lifetime `r` and returns a pointer with that same
|
||||
lifetime.
|
||||
|
||||
In general, it is only possible to return borrowed pointers if they
|
||||
In general, it is only possible to return references if they
|
||||
are derived from a parameter to the procedure. In that case, the
|
||||
pointer result will always have the same lifetime as one of the
|
||||
parameters; named lifetimes indicate which parameter that
|
||||
|
@ -532,10 +532,10 @@ fn get_x_sh(p: @Point) -> &f64 {
|
|||
~~~
|
||||
|
||||
Here, the function `get_x_sh()` takes a managed box as input and
|
||||
returns a borrowed pointer. As before, the lifetime of the borrowed
|
||||
pointer that will be returned is a parameter (specified by the
|
||||
caller). That means that `get_x_sh()` promises to return a borrowed
|
||||
pointer that is valid for as long as the caller would like: this is
|
||||
returns a reference. As before, the lifetime of the reference
|
||||
that will be returned is a parameter (specified by the
|
||||
caller). That means that `get_x_sh()` promises to return a reference
|
||||
that is valid for as long as the caller would like: this is
|
||||
subtly different from the first example, which promised to return a
|
||||
pointer that was valid for as long as its pointer argument was valid.
|
||||
|
||||
|
@ -551,10 +551,10 @@ valid at all once it returns, as the parameter `p` may or may not be
|
|||
live in the caller. Therefore, the compiler will report an error here.
|
||||
|
||||
In general, if you borrow a managed (or owned) box to create a
|
||||
borrowed pointer, the pointer will only be valid within the function
|
||||
and cannot be returned. This is why the typical way to return borrowed
|
||||
pointers is to take borrowed pointers as input (the only other case in
|
||||
which it can be legal to return a borrowed pointer is if the pointer
|
||||
reference, it will only be valid within the function
|
||||
and cannot be returned. This is why the typical way to return references
|
||||
is to take references as input (the only other case in
|
||||
which it can be legal to return a reference is if it
|
||||
points at a static constant).
|
||||
|
||||
# Named lifetimes
|
||||
|
@ -577,7 +577,7 @@ fn select<'r, T>(shape: &'r Shape, threshold: f64,
|
|||
}
|
||||
~~~
|
||||
|
||||
This function takes three borrowed pointers and assigns each the same
|
||||
This function takes three references and assigns each the same
|
||||
lifetime `r`. In practice, this means that, in the caller, the
|
||||
lifetime `r` will be the *intersection of the lifetime of the three
|
||||
region parameters*. This may be overly conservative, as in this
|
||||
|
@ -657,7 +657,7 @@ This is equivalent to the previous definition.
|
|||
|
||||
# Conclusion
|
||||
|
||||
So there you have it: a (relatively) brief tour of the borrowed pointer
|
||||
So there you have it: a (relatively) brief tour of the lifetime
|
||||
system. For more details, we refer to the (yet to be written) reference
|
||||
document on borrowed pointers, which will explain the full notation
|
||||
document on references, which will explain the full notation
|
||||
and give more examples.
|
||||
|
|
|
@ -86,8 +86,8 @@ common, such as C++, please read "A note..." below.
|
|||
or impossible. This is only often useful when a program is very large or very
|
||||
complicated. Using a managed pointer will activate Rust's garbage collection
|
||||
mechanism.
|
||||
5: Borrowed: You're writing a function, and you need a pointer, but you don't
|
||||
care about its ownership. If you make the argument a borrowed pointer, callers
|
||||
5: Reference: You're writing a function, and you need a pointer, but you don't
|
||||
care about its ownership. If you make the argument a reference, callers
|
||||
can send in whatever kind they want.
|
||||
|
||||
Five exceptions. That's it. Otherwise, you shouldn't need them. Be skeptical
|
||||
|
@ -313,11 +313,11 @@ drawback.
|
|||
concurrency boundaries is the source of endless pain in other langauges, so
|
||||
Rust does not let you do this.
|
||||
|
||||
# Borrowed Pointers
|
||||
# References
|
||||
|
||||
Borrowed pointers are the third major kind of pointer Rust supports. They are
|
||||
References are the third major kind of pointer Rust supports. They are
|
||||
simultaneously the simplest and the most complicated kind. Let me explain:
|
||||
they're called 'borrowed' pointers because they claim no ownership over the
|
||||
references are considered 'borrowed' because they claim no ownership over the
|
||||
data they're pointing to. They're just borrowing it for a while. So in that
|
||||
sense, they're simple: just keep whatever ownership the data already has. For
|
||||
example:
|
||||
|
@ -346,13 +346,13 @@ fn main() {
|
|||
~~~
|
||||
|
||||
This prints `5.83095189`. You can see that the `compute_distance` function
|
||||
takes in two borrowed pointers, but we give it a managed and unique pointer. Of
|
||||
takes in two references, but we give it a managed and unique pointer. Of
|
||||
course, if this were a real program, we wouldn't have any of these pointers,
|
||||
they're just there to demonstrate the concepts.
|
||||
|
||||
So how is this hard? Well, because we're igorning ownership, the compiler needs
|
||||
to take great care to make sure that everything is safe. Despite their complete
|
||||
safety, a borrowed pointer's representation at runtime is the same as that of
|
||||
safety, a reference's representation at runtime is the same as that of
|
||||
an ordinary pointer in a C program. They introduce zero overhead. The compiler
|
||||
does all safety checks at compile time.
|
||||
|
||||
|
@ -416,8 +416,8 @@ test.rs:4 let y = &x;
|
|||
~~~
|
||||
|
||||
As you might guess, this kind of analysis is complex for a human, and therefore
|
||||
hard for a computer, too! There is an entire [tutorial devoted to borrowed
|
||||
pointers and lifetimes](tutorial-lifetimes.html) that goes into lifetimes in
|
||||
hard for a computer, too! There is an entire [guide devoted to references
|
||||
and lifetimes](guide-lifetimes.html) that goes into lifetimes in
|
||||
great detail, so if you want the full details, check that out.
|
||||
|
||||
# Returning Pointers
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# Guides
|
||||
|
||||
[Pointers](guide-pointers.html)
|
||||
[Lifetimes](guide-lifetimes.html)
|
||||
[References and Lifetimes](guide-lifetimes.html)
|
||||
[Containers and Iterators](guide-container.html)
|
||||
[Tasks and Communication](guide-tasks.html)
|
||||
[Foreign Function Interface](guide-ffi.html)
|
||||
|
|
42
doc/rust.md
42
doc/rust.md
|
@ -1215,7 +1215,7 @@ A static item must have a _constant expression_ giving its definition.
|
|||
|
||||
Static items must be explicitly typed.
|
||||
The type may be ```bool```, ```char```, a number, or a type derived from those primitive types.
|
||||
The derived types are borrowed pointers with the `'static` lifetime,
|
||||
The derived types are references with the `'static` lifetime,
|
||||
fixed-size arrays, tuples, and structs.
|
||||
|
||||
~~~~
|
||||
|
@ -1841,7 +1841,7 @@ A complete list of the built-in language items follows:
|
|||
`owned`
|
||||
: Are uniquely owned.
|
||||
`durable`
|
||||
: Contain borrowed pointers.
|
||||
: Contain references.
|
||||
`drop`
|
||||
: Have finalizers.
|
||||
`add`
|
||||
|
@ -1898,11 +1898,11 @@ A complete list of the built-in language items follows:
|
|||
`free`
|
||||
: Free memory that was allocated on the managed heap.
|
||||
`borrow_as_imm`
|
||||
: Create an immutable borrowed pointer to a mutable value.
|
||||
: Create an immutable reference to a mutable value.
|
||||
`return_to_mut`
|
||||
: Release a borrowed pointer created with `return_to_mut`
|
||||
: Release a reference created with `return_to_mut`
|
||||
`check_not_borrowed`
|
||||
: Fail if a value has existing borrowed pointers to it.
|
||||
: Fail if a value has existing references to it.
|
||||
`strdup_uniq`
|
||||
: Return a new unique string
|
||||
containing a copy of the contents of a unique string.
|
||||
|
@ -2199,7 +2199,7 @@ When an lvalue is evaluated in an _lvalue context_, it denotes a memory location
|
|||
when evaluated in an _rvalue context_, it denotes the value held _in_ that memory location.
|
||||
|
||||
When an rvalue is used in lvalue context, a temporary un-named lvalue is created and used instead.
|
||||
A temporary's lifetime equals the largest lifetime of any borrowed pointer that points to it.
|
||||
A temporary's lifetime equals the largest lifetime of any reference that points to it.
|
||||
|
||||
#### Moved and copied types
|
||||
|
||||
|
@ -2403,8 +2403,8 @@ before the expression they apply to.
|
|||
: [Boxing](#pointer-types) operators. Allocate a box to hold the value they are applied to,
|
||||
and store the value in it. `@` creates a managed box, whereas `~` creates an owned box.
|
||||
`&`
|
||||
: Borrow operator. Returns a borrowed pointer, pointing to its operand.
|
||||
The operand of a borrowed pointer is statically proven to outlive the resulting pointer.
|
||||
: Borrow operator. Returns a reference, pointing to its operand.
|
||||
The operand of a borrow is statically proven to outlive the resulting pointer.
|
||||
If the borrow-checker cannot prove this, it is a compilation error.
|
||||
|
||||
### Binary operator expressions
|
||||
|
@ -2894,9 +2894,9 @@ match x {
|
|||
Patterns that bind variables
|
||||
default to binding to a copy or move of the matched value
|
||||
(depending on the matched value's type).
|
||||
This can be changed to bind to a borrowed pointer by
|
||||
This can be changed to bind to a reference by
|
||||
using the ```ref``` keyword,
|
||||
or to a mutable borrowed pointer using ```ref mut```.
|
||||
or to a mutable reference using ```ref mut```.
|
||||
|
||||
A pattern that's just an identifier,
|
||||
like `Nil` in the previous answer,
|
||||
|
@ -3172,18 +3172,18 @@ Owning pointers (`~`)
|
|||
it involves allocating a new owned box and copying the contents of the old box into the new box.
|
||||
Releasing an owning pointer immediately releases its corresponding owned box.
|
||||
|
||||
Borrowed pointers (`&`)
|
||||
References (`&`)
|
||||
: These point to memory _owned by some other value_.
|
||||
Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers,
|
||||
References arise by (automatic) conversion from owning pointers, managed pointers,
|
||||
or by applying the borrowing operator `&` to some other value,
|
||||
including [lvalues, rvalues or temporaries](#lvalues-rvalues-and-temporaries).
|
||||
Borrowed pointers are written `&content`, or in some cases `&'f content` for some lifetime-variable `f`,
|
||||
for example `&int` means a borrowed pointer to an integer.
|
||||
Copying a borrowed pointer is a "shallow" operation:
|
||||
References are written `&content`, or in some cases `&'f content` for some lifetime-variable `f`,
|
||||
for example `&int` means a reference to an integer.
|
||||
Copying a reference is a "shallow" operation:
|
||||
it involves only copying the pointer itself.
|
||||
Releasing a borrowed pointer typically has no effect on the value it points to,
|
||||
Releasing a reference typically has no effect on the value it points to,
|
||||
with the exception of temporary values,
|
||||
which are released when the last borrowed pointer to them is released.
|
||||
which are released when the last reference to them is released.
|
||||
|
||||
Raw pointers (`*`)
|
||||
: Raw pointers are pointers without safety or liveness guarantees.
|
||||
|
@ -3338,7 +3338,7 @@ The kinds are:
|
|||
This kind includes scalars and immutable references,
|
||||
as well as structural types containing other `Pod` types.
|
||||
`'static`
|
||||
: Types of this kind do not contain any borrowed pointers;
|
||||
: Types of this kind do not contain any references;
|
||||
this can be a useful guarantee for code
|
||||
that breaks borrowing assumptions
|
||||
using [`unsafe` operations](#unsafe-functions).
|
||||
|
@ -3417,14 +3417,14 @@ frame they are allocated within.
|
|||
### Memory ownership
|
||||
|
||||
A task owns all memory it can *safely* reach through local variables,
|
||||
as well as managed, owning and borrowed pointers.
|
||||
as well as managed, owned boxes and references.
|
||||
|
||||
When a task sends a value that has the `Send` trait to another task,
|
||||
it loses ownership of the value sent and can no longer refer to it.
|
||||
This is statically guaranteed by the combined use of "move semantics",
|
||||
and the compiler-checked _meaning_ of the `Send` trait:
|
||||
it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
|
||||
never including managed or borrowed pointers.
|
||||
never including managed boxes or references.
|
||||
|
||||
When a stack frame is exited, its local allocations are all released, and its
|
||||
references to boxes (both managed and owned) are dropped.
|
||||
|
@ -3569,7 +3569,7 @@ These include:
|
|||
- simple locks and semaphores
|
||||
|
||||
When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
|
||||
Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
|
||||
Restricting communication interfaces to this kind ensures that no references or managed pointers move between tasks.
|
||||
Thus access to an entire data structure can be mediated through its owning "root" value;
|
||||
no further locking or copying is required to avoid data races within the substructure of such a value.
|
||||
|
||||
|
|
|
@ -1341,11 +1341,12 @@ let mut y = ~5; // mutable
|
|||
*y += 2; // the * operator is needed to access the contained value
|
||||
~~~~
|
||||
|
||||
# Borrowed pointers
|
||||
# References
|
||||
|
||||
Rust's borrowed pointers are a general purpose reference type. In contrast with
|
||||
In contrast with
|
||||
owned boxes, where the holder of an owned box is the owner of the pointed-to
|
||||
memory, borrowed pointers never imply ownership. A pointer can be borrowed to
|
||||
memory, references never imply ownership - they are "borrowed".
|
||||
A reference can be borrowed to
|
||||
any object, and the compiler verifies that it cannot outlive the lifetime of
|
||||
the object.
|
||||
|
||||
|
@ -1377,7 +1378,7 @@ to define a function that takes two arguments of type point—that is,
|
|||
it takes the points by value. But this will cause the points to be
|
||||
copied when we call the function. For points, this is probably not so
|
||||
bad, but often copies are expensive. So we’d like to define a function
|
||||
that takes the points by pointer. We can use borrowed pointers to do this:
|
||||
that takes the points by pointer. We can use references to do this:
|
||||
|
||||
~~~
|
||||
# struct Point { x: f64, y: f64 }
|
||||
|
@ -1410,7 +1411,7 @@ route to the same data.
|
|||
|
||||
In the case of the boxes `managed_box` and `owned_box`, however, no
|
||||
explicit action is necessary. The compiler will automatically convert
|
||||
a box like `@point` or `~point` to a borrowed pointer like
|
||||
a box like `@point` or `~point` to a reference like
|
||||
`&point`. This is another form of borrowing; in this case, the
|
||||
contents of the managed/owned box are being lent out.
|
||||
|
||||
|
@ -1420,11 +1421,11 @@ have been lent out, you cannot send that variable to another task, nor
|
|||
will you be permitted to take actions that might cause the borrowed
|
||||
value to be freed or to change its type. This rule should make
|
||||
intuitive sense: you must wait for a borrowed value to be returned
|
||||
(that is, for the borrowed pointer to go out of scope) before you can
|
||||
(that is, for the reference to go out of scope) before you can
|
||||
make full use of it again.
|
||||
|
||||
For a more in-depth explanation of borrowed pointers and lifetimes, read the
|
||||
[lifetimes and borrowed pointer tutorial][lifetimes].
|
||||
For a more in-depth explanation of references and lifetimes, read the
|
||||
[references and lifetimes guide][lifetimes].
|
||||
|
||||
## Freezing
|
||||
|
||||
|
@ -1622,8 +1623,7 @@ defined in [`std::vec`] and [`std::str`].
|
|||
|
||||
# Ownership escape hatches
|
||||
|
||||
Ownership can cleanly describe tree-like data structures, and borrowed pointers provide non-owning
|
||||
references. However, more flexibility is often desired and Rust provides ways to escape from strict
|
||||
Ownership can cleanly describe tree-like data structures, and refercences provide non-owning pointers. However, more flexibility is often desired and Rust provides ways to escape from strict
|
||||
single parent ownership.
|
||||
|
||||
The standard library provides the `std::rc::Rc` pointer type to express *shared ownership* over a
|
||||
|
@ -1880,7 +1880,7 @@ A caller must in turn have a compatible pointer type to call the method.
|
|||
# Rectangle(Point, Point)
|
||||
# }
|
||||
impl Shape {
|
||||
fn draw_borrowed(&self) { ... }
|
||||
fn draw_reference(&self) { ... }
|
||||
fn draw_managed(@self) { ... }
|
||||
fn draw_owned(~self) { ... }
|
||||
fn draw_value(self) { ... }
|
||||
|
@ -1890,13 +1890,13 @@ let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0);
|
|||
|
||||
(@s).draw_managed();
|
||||
(~s).draw_owned();
|
||||
(&s).draw_borrowed();
|
||||
(&s).draw_reference();
|
||||
s.draw_value();
|
||||
~~~
|
||||
|
||||
Methods typically take a borrowed pointer self type,
|
||||
Methods typically take a reference self type,
|
||||
so the compiler will go to great lengths to convert a callee
|
||||
to a borrowed pointer.
|
||||
to a reference.
|
||||
|
||||
~~~
|
||||
# fn draw_circle(p: Point, f: f64) { }
|
||||
|
@ -1907,27 +1907,27 @@ to a borrowed pointer.
|
|||
# Rectangle(Point, Point)
|
||||
# }
|
||||
# impl Shape {
|
||||
# fn draw_borrowed(&self) { ... }
|
||||
# fn draw_reference(&self) { ... }
|
||||
# fn draw_managed(@self) { ... }
|
||||
# fn draw_owned(~self) { ... }
|
||||
# fn draw_value(self) { ... }
|
||||
# }
|
||||
# let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0);
|
||||
// As with typical function arguments, managed and owned pointers
|
||||
// are automatically converted to borrowed pointers
|
||||
// are automatically converted to references
|
||||
|
||||
(@s).draw_borrowed();
|
||||
(~s).draw_borrowed();
|
||||
(@s).draw_reference();
|
||||
(~s).draw_reference();
|
||||
|
||||
// Unlike typical function arguments, the self value will
|
||||
// automatically be referenced ...
|
||||
s.draw_borrowed();
|
||||
s.draw_reference();
|
||||
|
||||
// ... and dereferenced
|
||||
(& &s).draw_borrowed();
|
||||
(& &s).draw_reference();
|
||||
|
||||
// ... and dereferenced and borrowed
|
||||
(&@~s).draw_borrowed();
|
||||
(&@~s).draw_reference();
|
||||
~~~
|
||||
|
||||
Implementations may also define standalone (sometimes called "static")
|
||||
|
@ -2095,7 +2095,7 @@ and may not be overridden:
|
|||
|
||||
* `Send` - Sendable types.
|
||||
Types are sendable
|
||||
unless they contain managed boxes, managed closures, or borrowed pointers.
|
||||
unless they contain managed boxes, managed closures, or references.
|
||||
|
||||
* `Freeze` - Constant (immutable) types.
|
||||
These are types that do not contain anything intrinsically mutable.
|
||||
|
@ -2104,7 +2104,7 @@ Intrinsically mutable values include `Cell` in the standard library.
|
|||
* `'static` - Non-borrowed types.
|
||||
These are types that do not contain any data whose lifetime is bound to
|
||||
a particular stack frame. These are types that do not contain any
|
||||
borrowed pointers, or types where the only contained borrowed pointers
|
||||
references, or types where the only contained references
|
||||
have the `'static` lifetime.
|
||||
|
||||
> ***Note:*** These two traits were referred to as 'kinds' in earlier
|
||||
|
@ -2439,7 +2439,7 @@ order to be packaged up in a trait object of that storage class.
|
|||
|
||||
* The contents of owned traits (`~Trait`) must fulfill the `Send` bound.
|
||||
* The contents of managed traits (`@Trait`) must fulfill the `'static` bound.
|
||||
* The contents of borrowed traits (`&Trait`) are not constrained by any bound.
|
||||
* The contents of reference traits (`&Trait`) are not constrained by any bound.
|
||||
|
||||
Consequently, the trait objects themselves automatically fulfill their
|
||||
respective kind bounds. However, this default behavior can be overridden by
|
||||
|
|
|
@ -60,8 +60,8 @@ impl<A> Future<A> {
|
|||
|
||||
pub fn get_ref<'a>(&'a mut self) -> &'a A {
|
||||
/*!
|
||||
* Executes the future's closure and then returns a borrowed
|
||||
* pointer to the result. The borrowed pointer lasts as long as
|
||||
* Executes the future's closure and then returns a reference
|
||||
* to the result. The reference lasts as long as
|
||||
* the future.
|
||||
*/
|
||||
match self.state {
|
||||
|
|
|
@ -431,7 +431,7 @@ struct RWLockInner {
|
|||
// (or reader/downgrader) race.
|
||||
// By the way, if we didn't care about the assert in the read unlock path,
|
||||
// we could instead store the mode flag in write_downgrade's stack frame,
|
||||
// and have the downgrade tokens store a borrowed pointer to it.
|
||||
// and have the downgrade tokens store a reference to it.
|
||||
read_mode: bool,
|
||||
// The only way the count flag is ever accessed is with xadd. Since it is
|
||||
// a read-modify-write operation, multiple xadds on different cores will
|
||||
|
|
|
@ -44,7 +44,7 @@ referent).
|
|||
It then uses the dataflow module to propagate which of those borrows
|
||||
may be in scope at each point in the procedure. A loan is considered
|
||||
to come into scope at the expression that caused it and to go out of
|
||||
scope when the lifetime of the resulting borrowed pointer expires.
|
||||
scope when the lifetime of the resulting reference expires.
|
||||
|
||||
Once the in-scope loans are known for each point in the program, the
|
||||
borrow checker walks the IR again in a second pass called
|
||||
|
@ -146,14 +146,14 @@ result of the borrow `&mut (*x).f` in the example above:
|
|||
|
||||
The loan states that the expression `(*x).f` has been loaned as
|
||||
mutable for the lifetime `'a`. Because the loan is mutable, that means
|
||||
that the value `(*x).f` may be mutated via the newly created borrowed
|
||||
pointer (and *only* via that pointer). This is reflected in the
|
||||
that the value `(*x).f` may be mutated via the newly created reference
|
||||
(and *only* via that pointer). This is reflected in the
|
||||
restrictions `RS` that accompany the loan.
|
||||
|
||||
The first restriction `((*x).f, [MUTATE, CLAIM, FREEZE])` states that
|
||||
the lender may not mutate nor freeze `(*x).f`. Mutation is illegal
|
||||
because `(*x).f` is only supposed to be mutated via the new borrowed
|
||||
pointer, not by mutating the original path `(*x).f`. Freezing is
|
||||
because `(*x).f` is only supposed to be mutated via the new reference,
|
||||
not by mutating the original path `(*x).f`. Freezing is
|
||||
illegal because the path now has an `&mut` alias; so even if we the
|
||||
lender were to consider `(*x).f` to be immutable, it might be mutated
|
||||
via this alias. Both of these restrictions are temporary. They will be
|
||||
|
@ -164,8 +164,8 @@ The second restriction on `*x` is interesting because it does not
|
|||
apply to the path that was lent (`(*x).f`) but rather to a prefix of
|
||||
the borrowed path. This is due to the rules of inherited mutability:
|
||||
if the user were to assign to (or freeze) `*x`, they would indirectly
|
||||
overwrite (or freeze) `(*x).f`, and thus invalidate the borrowed
|
||||
pointer that was created. In general it holds that when a path is
|
||||
overwrite (or freeze) `(*x).f`, and thus invalidate the reference
|
||||
that was created. In general it holds that when a path is
|
||||
lent, restrictions are issued for all the owning prefixes of that
|
||||
path. In this case, the path `*x` owns the path `(*x).f` and,
|
||||
because `x` is an owned pointer, the path `x` owns the path `*x`.
|
||||
|
@ -241,7 +241,7 @@ lvalue `LV` being borrowed and the mutability `MQ` and lifetime `LT`
|
|||
of the resulting pointer. Given those, `gather_loans` applies three
|
||||
validity tests:
|
||||
|
||||
1. `MUTABILITY(LV, MQ)`: The mutability of the borrowed pointer is
|
||||
1. `MUTABILITY(LV, MQ)`: The mutability of the reference is
|
||||
compatible with the mutability of `LV` (i.e., not borrowing immutable
|
||||
data as mutable).
|
||||
|
||||
|
@ -380,9 +380,9 @@ of its owner:
|
|||
TYPE(LV) = ~Ty
|
||||
LIFETIME(LV, LT, MQ)
|
||||
|
||||
### Checking lifetime for derefs of borrowed pointers
|
||||
### Checking lifetime for derefs of references
|
||||
|
||||
Borrowed pointers have a lifetime `LT'` associated with them. The
|
||||
References have a lifetime `LT'` associated with them. The
|
||||
data they point at has been guaranteed to be valid for at least this
|
||||
lifetime. Therefore, the borrow is valid so long as the lifetime `LT`
|
||||
of the borrow is shorter than the lifetime `LT'` of the pointer
|
||||
|
@ -412,7 +412,7 @@ value is not mutated or moved. Note that lvalues are either
|
|||
(ultimately) owned by a local variable, in which case we can check
|
||||
whether that local variable is ever moved in its scope, or they are
|
||||
owned by the referent of an (immutable, due to condition 2) managed or
|
||||
borrowed pointer, in which case moves are not permitted because the
|
||||
references, in which case moves are not permitted because the
|
||||
location is aliasable.
|
||||
|
||||
If the conditions of `L-Deref-Managed-Imm-User-Root` are not met, then
|
||||
|
|
|
@ -662,7 +662,7 @@ impl<'a> GatherLoanCtxt<'a> {
|
|||
//! &mut v.counter
|
||||
//! }
|
||||
//!
|
||||
//! In this case, the borrowed pointer (`'a`) outlives the
|
||||
//! In this case, the reference (`'a`) outlives the
|
||||
//! variable `v` that hosts it. Note that this doesn't come up
|
||||
//! with immutable `&` pointers, because borrows of such pointers
|
||||
//! do not require restrictions and hence do not cause a loan.
|
||||
|
|
|
@ -719,7 +719,7 @@ impl BorrowckCtxt {
|
|||
err_out_of_scope(super_scope, sub_scope) => {
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
"borrowed pointer must be valid for ",
|
||||
"reference must be valid for ",
|
||||
sub_scope,
|
||||
"...");
|
||||
note_and_explain_region(
|
||||
|
|
|
@ -192,7 +192,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
|
|||
ExprAddrOf(..) => {
|
||||
sess.span_err(
|
||||
e.span,
|
||||
"borrowed pointers in constants may only refer to \
|
||||
"references in constants may only refer to \
|
||||
immutable values");
|
||||
},
|
||||
ExprVstore(_, ExprVstoreUniq) |
|
||||
|
|
|
@ -33,7 +33,7 @@ use syntax::visit::Visitor;
|
|||
// send: Things that can be sent on channels or included in spawned closures.
|
||||
// freeze: Things thare are deeply immutable. They are guaranteed never to
|
||||
// change, and can be safely shared without copying between tasks.
|
||||
// 'static: Things that do not contain borrowed pointers.
|
||||
// 'static: Things that do not contain references.
|
||||
//
|
||||
// Send includes scalar types as well as classes and unique types containing
|
||||
// only sendable types.
|
||||
|
@ -487,12 +487,11 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: Span) -> bool {
|
|||
if !ty::type_is_static(tcx, ty) {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_param(..) => {
|
||||
tcx.sess.span_err(sp, "value may contain borrowed \
|
||||
pointers; add `'static` bound");
|
||||
tcx.sess.span_err(sp, "value may contain references; \
|
||||
add `'static` bound");
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_err(sp, "value may contain borrowed \
|
||||
pointers");
|
||||
tcx.sess.span_err(sp, "value may contain references");
|
||||
}
|
||||
}
|
||||
false
|
||||
|
@ -502,10 +501,10 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: Span) -> bool {
|
|||
}
|
||||
|
||||
/// This is rather subtle. When we are casting a value to a instantiated
|
||||
/// trait like `a as trait<'r>`, regionck already ensures that any borrowed
|
||||
/// pointers that appear in the type of `a` are bounded by `'r` (ed.: rem
|
||||
/// trait like `a as trait<'r>`, regionck already ensures that any references
|
||||
/// that appear in the type of `a` are bounded by `'r` (ed.: rem
|
||||
/// FIXME(#5723)). However, it is possible that there are *type parameters*
|
||||
/// in the type of `a`, and those *type parameters* may have borrowed pointers
|
||||
/// in the type of `a`, and those *type parameters* may have references
|
||||
/// within them. We have to guarantee that the regions which appear in those
|
||||
/// type parameters are not obscured.
|
||||
///
|
||||
|
@ -513,17 +512,17 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: Span) -> bool {
|
|||
///
|
||||
/// (1) The trait instance cannot escape the current fn. This is
|
||||
/// guaranteed if the region bound `&r` is some scope within the fn
|
||||
/// itself. This case is safe because whatever borrowed pointers are
|
||||
/// itself. This case is safe because whatever references are
|
||||
/// found within the type parameter, they must enclose the fn body
|
||||
/// itself.
|
||||
///
|
||||
/// (2) The type parameter appears in the type of the trait. For
|
||||
/// example, if the type parameter is `T` and the trait type is
|
||||
/// `deque<T>`, then whatever borrowed ptrs may appear in `T` also
|
||||
/// `deque<T>`, then whatever references may appear in `T` also
|
||||
/// appear in `deque<T>`.
|
||||
///
|
||||
/// (3) The type parameter is sendable (and therefore does not contain
|
||||
/// borrowed ptrs).
|
||||
/// references).
|
||||
///
|
||||
/// FIXME(#5723)---This code should probably move into regionck.
|
||||
pub fn check_cast_for_escaping_regions(
|
||||
|
@ -573,7 +572,7 @@ pub fn check_cast_for_escaping_regions(
|
|||
// if !target_regions.iter().any(|t_r| is_subregion_of(cx, *t_r, r)) {
|
||||
// cx.tcx.sess.span_err(
|
||||
// source_span,
|
||||
// format!("source contains borrowed pointer with lifetime \
|
||||
// format!("source contains reference with lifetime \
|
||||
// not found in the target type `{}`",
|
||||
// ty_to_str(cx.tcx, target_ty)));
|
||||
// note_and_explain_region(
|
||||
|
|
|
@ -612,7 +612,7 @@ impl VisitContext {
|
|||
self.use_receiver(receiver_expr);
|
||||
|
||||
// for overloaded operatrs, we are always passing in a
|
||||
// borrowed pointer, so it's always read mode:
|
||||
// reference, so it's always read mode:
|
||||
for arg_expr in arg_exprs.iter() {
|
||||
self.use_expr(*arg_expr, Read);
|
||||
}
|
||||
|
|
|
@ -1752,7 +1752,7 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
|
|||
* think of them as kind of an "anti-kind". They track the kinds of values
|
||||
* and thinks that are contained in types. Having a larger contents for
|
||||
* a type tends to rule that type *out* from various kinds. For example,
|
||||
* a type that contains a borrowed pointer is not sendable.
|
||||
* a type that contains a reference is not sendable.
|
||||
*
|
||||
* The reason we compute type contents and not kinds is that it is
|
||||
* easier for me (nmatsakis) to think about what is contained within
|
||||
|
@ -2188,7 +2188,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
|||
mutbl: ast::Mutability)
|
||||
-> TypeContents {
|
||||
/*!
|
||||
* Type contents due to containing a borrowed pointer
|
||||
* Type contents due to containing a reference
|
||||
* with the region `region` and borrow kind `bk`
|
||||
*/
|
||||
|
||||
|
|
|
@ -789,10 +789,10 @@ fn constrain_regions_in_type(
|
|||
pub mod guarantor {
|
||||
/*!
|
||||
* The routines in this module are aiming to deal with the case
|
||||
* where a the contents of a borrowed pointer are re-borrowed.
|
||||
* Imagine you have a borrowed pointer `b` with lifetime L1 and
|
||||
* where a the contents of a reference are re-borrowed.
|
||||
* Imagine you have a reference `b` with lifetime L1 and
|
||||
* you have an expression `&*b`. The result of this borrow will
|
||||
* be another borrowed pointer with lifetime L2 (which is an
|
||||
* be another reference with lifetime L2 (which is an
|
||||
* inference variable). The borrow checker is going to enforce
|
||||
* the constraint that L2 < L1, because otherwise you are
|
||||
* re-borrowing data for a lifetime larger than the original loan.
|
||||
|
@ -815,15 +815,15 @@ pub mod guarantor {
|
|||
* a borrow.
|
||||
*
|
||||
* The key point here is that when you are borrowing a value that
|
||||
* is "guaranteed" by a borrowed pointer, you must link the
|
||||
* lifetime of that borrowed pointer (L1, here) to the lifetime of
|
||||
* is "guaranteed" by a reference, you must link the
|
||||
* lifetime of that reference (L1, here) to the lifetime of
|
||||
* the borrow itself (L2). What do I mean by "guaranteed" by a
|
||||
* borrowed pointer? I mean any data that is reached by first
|
||||
* dereferencing a borrowed pointer and then either traversing
|
||||
* reference? I mean any data that is reached by first
|
||||
* dereferencing a reference and then either traversing
|
||||
* interior offsets or owned pointers. We say that the guarantor
|
||||
* of such data it the region of the borrowed pointer that was
|
||||
* of such data it the region of the reference that was
|
||||
* traversed. This is essentially the same as the ownership
|
||||
* relation, except that a borrowed pointer never owns its
|
||||
* relation, except that a reference never owns its
|
||||
* contents.
|
||||
*
|
||||
* NB: I really wanted to use the `mem_categorization` code here
|
||||
|
@ -953,7 +953,7 @@ pub mod guarantor {
|
|||
guarantor: Option<ty::Region>) {
|
||||
/*!
|
||||
*
|
||||
* Links the lifetime of the borrowed pointer resulting from a borrow
|
||||
* Links the lifetime of the reference resulting from a borrow
|
||||
* to the lifetime of its guarantor (if any).
|
||||
*/
|
||||
|
||||
|
@ -1134,7 +1134,7 @@ pub mod guarantor {
|
|||
Some(ty::AutoBorrowFn(r)) |
|
||||
Some(ty::AutoBorrowObj(r, _)) => {
|
||||
// If there is an autoref, then the result of this
|
||||
// expression will be some sort of borrowed pointer.
|
||||
// expression will be some sort of reference.
|
||||
expr_ct.cat.guarantor = None;
|
||||
expr_ct.cat.pointer = BorrowedPointer(r);
|
||||
debug!("autoref, cat={:?}", expr_ct.cat);
|
||||
|
|
|
@ -146,7 +146,7 @@ pub fn relate_free_regions(
|
|||
* for each function just before we check the body of that
|
||||
* function, looking for types where you have a borrowed
|
||||
* pointer to other borrowed data (e.g., `&'a &'b [uint]`.
|
||||
* We do not allow borrowed pointers to outlive the things they
|
||||
* We do not allow references to outlive the things they
|
||||
* point at, so we can assume that `'a <= 'b`.
|
||||
*
|
||||
* Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
|
||||
|
|
|
@ -20,8 +20,8 @@ but not in representation (so actual subtyping is inappropriate).
|
|||
|
||||
## Reborrowing
|
||||
|
||||
Note that if we are expecting a borrowed pointer, we will *reborrow*
|
||||
even if the argument provided was already a borrowed pointer. This is
|
||||
Note that if we are expecting a reference, we will *reborrow*
|
||||
even if the argument provided was already a reference. This is
|
||||
useful for freezing mut/const things (that is, when the expected is &T
|
||||
but you have &const T or &mut T) and also for avoiding the linearity
|
||||
of mut things (when the expected is &mut T and you have &mut T). See
|
||||
|
@ -451,7 +451,7 @@ impl Coerce {
|
|||
let a_unsafe = ty::mk_ptr(self.get_ref().infcx.tcx, mt_a);
|
||||
if_ok!(self.subtype(a_unsafe, b));
|
||||
|
||||
// although borrowed ptrs and unsafe ptrs have the same
|
||||
// although references and unsafe ptrs have the same
|
||||
// representation, we still register an AutoDerefRef so that
|
||||
// regionck knows that the region for `a` must be valid here
|
||||
Ok(Some(@AutoDerefRef(AutoDerefRef {
|
||||
|
|
|
@ -226,11 +226,11 @@ impl ErrorReporting for InferCtxt {
|
|||
infer::Reborrow(span) => {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"lifetime of borrowed pointer outlines \
|
||||
"lifetime of reference outlines \
|
||||
lifetime of borrowed content...");
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
"...the borrowed pointer is valid for ",
|
||||
"...the reference is valid for ",
|
||||
sub,
|
||||
"...");
|
||||
note_and_explain_region(
|
||||
|
@ -351,7 +351,7 @@ impl ErrorReporting for InferCtxt {
|
|||
infer::AddrOf(span) => {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"borrowed pointer is not valid \
|
||||
"reference is not valid \
|
||||
at the time of borrow");
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
|
@ -362,7 +362,7 @@ impl ErrorReporting for InferCtxt {
|
|||
infer::AutoBorrow(span) => {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"automatically borrowed pointer is not valid \
|
||||
"automatically reference is not valid \
|
||||
at the time of borrow");
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
|
@ -532,7 +532,7 @@ impl ErrorReportingHelpers for InferCtxt {
|
|||
infer::Reborrow(span) => {
|
||||
self.tcx.sess.span_note(
|
||||
span,
|
||||
"...so that borrowed pointer does not outlive \
|
||||
"...so that reference does not outlive \
|
||||
borrowed content");
|
||||
}
|
||||
infer::InfStackClosure(span) => {
|
||||
|
@ -586,13 +586,13 @@ impl ErrorReportingHelpers for InferCtxt {
|
|||
infer::AddrOf(span) => {
|
||||
self.tcx.sess.span_note(
|
||||
span,
|
||||
"...so that borrowed pointer is valid \
|
||||
"...so that reference is valid \
|
||||
at the time of borrow");
|
||||
}
|
||||
infer::AutoBorrow(span) => {
|
||||
self.tcx.sess.span_note(
|
||||
span,
|
||||
"...so that automatically borrowed pointer is valid \
|
||||
"...so that automatically reference is valid \
|
||||
at the time of borrow");
|
||||
}
|
||||
infer::BindingTypeIsNotValidAtDecl(span) => {
|
||||
|
|
|
@ -157,7 +157,7 @@ pub enum SubregionOrigin {
|
|||
// Invocation of closure must be within its lifetime
|
||||
InvokeClosure(Span),
|
||||
|
||||
// Dereference of borrowed pointer must be within its lifetime
|
||||
// Dereference of reference must be within its lifetime
|
||||
DerefPointer(Span),
|
||||
|
||||
// Closure bound must not outlive captured free variables
|
||||
|
@ -170,7 +170,7 @@ pub enum SubregionOrigin {
|
|||
// relating `'a` to `'b`
|
||||
RelateObjectBound(Span),
|
||||
|
||||
// Creating a pointer `b` to contents of another borrowed pointer
|
||||
// Creating a pointer `b` to contents of another reference
|
||||
Reborrow(Span),
|
||||
|
||||
// (&'a &'b T) where a >= b
|
||||
|
|
|
@ -226,12 +226,12 @@ corresponds to the *actual execution of the function `add()`*, after
|
|||
all arguments have been evaluated. There is a corresponding lifetime
|
||||
`'b_call` for the execution of `inc()`. If we wanted to be precise
|
||||
about it, the lifetime of the two borrows should be `'a_call` and
|
||||
`'b_call` respectively, since the borrowed pointers that were created
|
||||
`'b_call` respectively, since the references that were created
|
||||
will not be dereferenced except during the execution itself.
|
||||
|
||||
However, this model by itself is not sound. The reason is that
|
||||
while the two borrowed pointers that are created will never be used
|
||||
simultaneously, it is still true that the first borrowed pointer is
|
||||
while the two references that are created will never be used
|
||||
simultaneously, it is still true that the first reference is
|
||||
*created* before the second argument is evaluated, and so even though
|
||||
it will not be *dereferenced* during the evaluation of the second
|
||||
argument, it can still be *invalidated* by that evaluation. Consider
|
||||
|
@ -257,7 +257,7 @@ invalidating the first argument.
|
|||
So, for now, we exclude the `call` lifetimes from our model.
|
||||
Eventually I would like to include them, but we will have to make the
|
||||
borrow checker handle this situation correctly. In particular, if
|
||||
there is a borrowed pointer created whose lifetime does not enclose
|
||||
there is a reference created whose lifetime does not enclose
|
||||
the borrow expression, we must issue sufficient restrictions to ensure
|
||||
that the pointee remains valid.
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ use syntax::opt_vec::OptVec;
|
|||
|
||||
/// Defines strategies for handling regions that are omitted. For
|
||||
/// example, if one writes the type `&Foo`, then the lifetime of of
|
||||
/// this borrowed pointer has been omitted. When converting this
|
||||
/// this reference has been omitted. When converting this
|
||||
/// type, the generic functions in astconv will invoke `anon_regions`
|
||||
/// on the provided region-scope to decide how to translate this
|
||||
/// omitted region.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Borrowed pointer utilities
|
||||
//! Utilities for references
|
||||
|
||||
#[cfg(not(test))]
|
||||
use prelude::*;
|
||||
|
|
|
@ -64,7 +64,7 @@ pub unsafe fn transmute<L, G>(thing: L) -> G {
|
|||
#[inline]
|
||||
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
|
||||
|
||||
/// Coerce a borrowed pointer to have an arbitrary associated region.
|
||||
/// Coerce a reference to have an arbitrary associated region.
|
||||
#[inline]
|
||||
pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
|
||||
transmute(ptr)
|
||||
|
@ -82,7 +82,7 @@ pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
|
|||
transmute(ptr)
|
||||
}
|
||||
|
||||
/// Coerce a borrowed mutable pointer to have an arbitrary associated region.
|
||||
/// Coerce a mutable reference to have an arbitrary associated region.
|
||||
#[inline]
|
||||
pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
|
||||
transmute(ptr)
|
||||
|
|
|
@ -59,7 +59,7 @@ impl<T> Clone for @T {
|
|||
}
|
||||
|
||||
impl<'a, T> Clone for &'a T {
|
||||
/// Return a shallow copy of the borrowed pointer.
|
||||
/// Return a shallow copy of the reference.
|
||||
#[inline]
|
||||
fn clone(&self) -> &'a T { *self }
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
//! `std` includes modules corresponding to each of the integer types,
|
||||
//! each of the floating point types, the `bool` type, tuples, characters,
|
||||
//! strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
|
||||
//! boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
|
||||
//! boxes (`owned`), and unsafe pointers and references (`ptr`, `borrowed`).
|
||||
//! Additionally, `std` provides pervasive types (`option` and `result`),
|
||||
//! task creation and communication primitives (`task`, `comm`), platform
|
||||
//! abstractions (`os` and `path`), basic I/O abstractions (`io`), common
|
||||
|
|
|
@ -71,7 +71,7 @@ traits from other modules. Some notable examples:
|
|||
## Iteration
|
||||
|
||||
The method `iter()` returns an iteration value for a vector or a vector slice.
|
||||
The iterator yields borrowed pointers to the vector's elements, so if the element
|
||||
The iterator yields references to the vector's elements, so if the element
|
||||
type of the vector is `int`, the element type of the iterator is `&int`.
|
||||
|
||||
```rust
|
||||
|
|
|
@ -371,7 +371,7 @@ pub enum Pat_ {
|
|||
PatTup(~[@Pat]),
|
||||
PatBox(@Pat),
|
||||
PatUniq(@Pat),
|
||||
PatRegion(@Pat), // borrowed pointer pattern
|
||||
PatRegion(@Pat), // reference pattern
|
||||
PatLit(@Expr),
|
||||
PatRange(@Expr, @Expr),
|
||||
// [a, b, ..i, y, z] is represented as
|
||||
|
|
|
@ -26,7 +26,7 @@ Supported features (fairly exhaustive):
|
|||
requires an explicit `Eq` bound at the
|
||||
moment. (`TraitDef.additional_bounds`)
|
||||
|
||||
Unsupported: FIXME #6257: calling methods on borrowed pointer fields,
|
||||
Unsupported: FIXME #6257: calling methods on reference fields,
|
||||
e.g. deriving TotalEq/TotalOrd/Clone don't work on `struct A(&int)`,
|
||||
because of how the auto-dereferencing happens.
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> {
|
|||
}
|
||||
|
||||
// A StrInterner differs from Interner<String> in that it accepts
|
||||
// borrowed pointers rather than @ ones, resulting in less allocation.
|
||||
// references rather than @ ones, resulting in less allocation.
|
||||
pub struct StrInterner {
|
||||
priv map: @RefCell<HashMap<@str, Name>>,
|
||||
priv vect: @RefCell<~[@str]>,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[feature(managed_boxes)];
|
||||
|
||||
fn f<T>(x: T) -> @T {
|
||||
@x //~ ERROR value may contain borrowed pointers
|
||||
@x //~ ERROR value may contain references
|
||||
}
|
||||
|
||||
fn g<T:'static>(x: T) -> @T {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Testing that we can't store a borrowed pointer it task-local storage
|
||||
// Testing that we can't store a reference it task-local storage
|
||||
|
||||
use std::local_data;
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ impl<T:Clone> foo for T {
|
|||
}
|
||||
|
||||
fn to_foo<T:Clone>(t: T) {
|
||||
// This version is ok because, although T may contain borrowed
|
||||
// pointers, it never escapes the fn body. We know this because
|
||||
// This version is ok because, although T may contain references
|
||||
// it never escapes the fn body. We know this because
|
||||
// the type of foo includes a region which will be resolved to
|
||||
// the fn body itself.
|
||||
let v = &3;
|
||||
|
@ -34,15 +34,15 @@ fn to_foo<T:Clone>(t: T) {
|
|||
}
|
||||
|
||||
fn to_foo_2<T:Clone>(t: T) -> @foo {
|
||||
// Not OK---T may contain borrowed ptrs and it is going to escape
|
||||
// Not OK---T may contain references and it is going to escape
|
||||
// as part of the returned foo value
|
||||
struct F<T> { f: T }
|
||||
@F {f:t} as @foo //~ ERROR value may contain borrowed pointers; add `'static` bound
|
||||
@F {f:t} as @foo //~ ERROR value may contain references; add `'static` bound
|
||||
}
|
||||
|
||||
fn to_foo_3<T:Clone + 'static>(t: T) -> @foo {
|
||||
// OK---T may escape as part of the returned foo value, but it is
|
||||
// owned and hence does not contain borrowed ptrs
|
||||
// owned and hence does not contain references
|
||||
struct F<T> { f: T }
|
||||
@F {f:t} as @foo
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ trait foo { fn foo(&self); }
|
|||
|
||||
fn to_foo<T:Clone + foo>(t: T) -> @foo {
|
||||
@t as @foo
|
||||
//~^ ERROR value may contain borrowed pointers; add `'static` bound
|
||||
//~^ ERROR value may contain references; add `'static` bound
|
||||
//~^^ ERROR cannot pack type
|
||||
//~^^^ ERROR value may contain borrowed pointers
|
||||
//~^^^ ERROR value may contain references
|
||||
}
|
||||
|
||||
fn to_foo2<T:Clone + foo + 'static>(t: T) -> @foo {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// xfail-test #5723
|
||||
|
||||
// Test that you cannot escape a borrowed pointer
|
||||
// Test that you cannot escape a reference
|
||||
// into a trait.
|
||||
|
||||
struct ctxt { v: uint }
|
||||
|
@ -29,7 +29,7 @@ fn make_gc() -> @get_ctxt {
|
|||
let ctxt = ctxt { v: 22u };
|
||||
let hc = has_ctxt { c: &ctxt };
|
||||
return @hc as @get_ctxt;
|
||||
//^~ ERROR source contains borrowed pointer
|
||||
//^~ ERROR source contains reference
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -175,10 +175,10 @@ fn main() {
|
|||
// managed box
|
||||
let @aa = @(34, 35);
|
||||
|
||||
// borrowed pointer
|
||||
// reference
|
||||
let &bb = &(36, 37);
|
||||
|
||||
// contained borrowed pointer
|
||||
// contained reference
|
||||
let (&cc, _) = (&38, 39);
|
||||
|
||||
// unique pointer
|
||||
|
|
|
@ -51,7 +51,7 @@ struct AsciiArt {
|
|||
priv lines: ~[~[char]],
|
||||
|
||||
// This struct can be quite large so we'll disable copying: developers need
|
||||
// to either pass these structs around via borrowed pointers or move them.
|
||||
// to either pass these structs around via references or move them.
|
||||
}
|
||||
|
||||
impl Drop for AsciiArt {
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
// except according to those terms.
|
||||
|
||||
/*
|
||||
# ICE when returning struct with borrowed pointer to trait
|
||||
# ICE when returning struct with reference to trait
|
||||
|
||||
A function which takes a borrowed pointer to a trait and returns a
|
||||
struct with that borrowed pointer results in an ICE.
|
||||
A function which takes a reference to a trait and returns a
|
||||
struct with that reference results in an ICE.
|
||||
|
||||
This does not occur with concrete types, only with borrowed pointers
|
||||
This does not occur with concrete types, only with references
|
||||
to traits.
|
||||
*/
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue