about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-23 12:01:53 -0700
committerbors <bors@rust-lang.org>2014-04-23 12:01:53 -0700
commit6beb376b5c27c6b028092f227f865ba564fea17b (patch)
treeb52fa55b56bb4c1b21d1753c7d5c2402894d3c9b /src/libstd/rt
parentb5dd3f05fe95168b5569d0f519636149479eb6ac (diff)
parent823c7eee6a040862abb5a5309693030394200e62 (diff)
downloadrust-6beb376b5c27c6b028092f227f865ba564fea17b.tar.gz
rust-6beb376b5c27c6b028092f227f865ba564fea17b.zip
auto merge of #13686 : alexcrichton/rust/issue-12224, r=nikomatsakis
This alters the borrow checker's requirements on invoking closures from
requiring an immutable borrow to requiring a unique immutable borrow. This means 
that it is illegal to invoke a closure through a `&` pointer because there is no 
guarantee that is not aliased. This does not mean that a closure is required to
be in a mutable location, but rather a location which can be proven to be
unique (often through a mutable pointer).
                                                                                 
For example, the following code is unsound and is no longer allowed:             
                                                                                 
    type Fn<'a> = ||:'a;                                                         
                                                                                 
    fn call(f: |Fn|) {                                                           
        f(|| {                                                                   
            f(|| {})                                                             
        });                                                                      
    }                                                                            
                                                                                 
    fn main() {                                                                  
        call(|a| {                                                               
            a();                                                                 
        });                                                                      
    }                                                                            
                                                                                 
There is no replacement for this pattern. For all closures which are stored in
structures, it was previously allowed to invoke the closure through `&self` but
it now requires invocation through `&mut self`.

The standard library has a good number of violations of this new rule, but the
fixes will be separated into multiple breaking change commits.
                                                                                 
Closes #12224                                                                    
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/task.rs2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index f75b5315207..2dab0e975da 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -109,7 +109,7 @@ impl Task {
     /// This function is *not* meant to be abused as a "try/catch" block. This
     /// is meant to be used at the absolute boundaries of a task's lifetime, and
     /// only for that purpose.
-    pub fn run(~self, f: ||) -> ~Task {
+    pub fn run(~self, mut f: ||) -> ~Task {
         // Need to put ourselves into TLS, but also need access to the unwinder.
         // Unsafely get a handle to the task so we can continue to use it after
         // putting it in tls (so we can invoke the unwinder).