]> git.lizzy.rs Git - rust.git/commitdiff
Treat loans of 'static data as extending to the end of the enclosing
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 9 Sep 2015 20:04:55 +0000 (16:04 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 9 Sep 2015 20:04:55 +0000 (16:04 -0400)
fn. Fixes #27616.

src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/test/borrowck-loan-of-static-data-issue-27616.rs [new file with mode: 0644]

index 505c66593f5eb404d5674c1f4b4cc8ef96d4cc7d..56cd7e5eaa8901bb891fab8752caf2668c2c5972 100644 (file)
@@ -364,17 +364,7 @@ fn guarantee_valid(&mut self,
 
                     ty::ReFree(ref fr) => fr.scope,
 
-                    ty::ReStatic => {
-                        // If we get here, an error must have been
-                        // reported in
-                        // `lifetime::guarantee_lifetime()`, because
-                        // the only legal ways to have a borrow with a
-                        // static lifetime should not require
-                        // restrictions. To avoid reporting derived
-                        // errors, we just return here without adding
-                        // any loans.
-                        return;
-                    }
+                    ty::ReStatic => self.item_ub,
 
                     ty::ReEmpty |
                     ty::ReLateBound(..) |
diff --git a/src/test/borrowck-loan-of-static-data-issue-27616.rs b/src/test/borrowck-loan-of-static-data-issue-27616.rs
new file mode 100644 (file)
index 0000000..228e710
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::mem;
+
+fn leak<T>(mut b: Box<T>) -> &'static mut T {
+    // isn't this supposed to be safe?
+    let inner = &mut *b as *mut _;
+    mem::forget(b);
+    unsafe { &mut *inner }
+}
+
+fn evil(mut s: &'static mut String)
+{
+    // create alias
+    let alias: &'static mut String = s;
+    let inner: &str = &alias;
+    // free value
+    *s = String::new(); //~ ERROR cannot assign
+    let _spray = "0wned".to_owned();
+    // ... and then use it
+    println!("{}", inner);
+}
+
+fn main() {
+    evil(leak(Box::new("hello".to_owned())));
+}