Skip to content

Commit 30dafcb

Browse files
committed
Allow move out of immutable static
Fixes rust-lang#13233
1 parent b8ef9fd commit 30dafcb

File tree

5 files changed

+62
-14
lines changed

5 files changed

+62
-14
lines changed

src/librustc/middle/borrowck/gather_loans/gather_moves.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
117117
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
118118
mc::cat_deref(_, _, mc::GcPtr) |
119119
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
120-
mc::cat_upvar(..) | mc::cat_static_item |
120+
mc::cat_upvar(..) |
121121
mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => {
122122
bccx.span_err(
123123
cmt0.span,
@@ -126,6 +126,19 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
126126
false
127127
}
128128

129+
mc::cat_static_item => {
130+
match cmt.mutbl {
131+
// "Moves" out of static items end-up calling memcpy, so they are allowed.
132+
mc::McImmutable => {
133+
true
134+
}
135+
_ => {
136+
bccx.span_err( cmt0.span, "cannot move out of mutable static items");
137+
false
138+
}
139+
}
140+
}
141+
129142
// Can move out of captured upvars only if the destination closure
130143
// type is 'once'. 1-shot stack closures emit the copied_upvar form
131144
// (see mem_categorization.rs).

src/test/compile-fail/static-items-cant-move.rs renamed to src/test/compile-fail/cant-move-out-of-mutable-static.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Verifies that static items can't be moved
11+
// Ensure that moves out of mutable static items is disallowed
1212

1313
use std::kinds::marker;
1414

@@ -17,13 +17,11 @@ struct Foo {
1717
nocopy: marker::NoCopy
1818
}
1919

20-
static BAR: Foo = Foo{foo: 5, nocopy: marker::NoCopy};
21-
22-
23-
fn test(f: Foo) {
24-
let _f = Foo{foo: 4, ..f};
25-
}
20+
static mut BAR: Foo = Foo{foo: 5, nocopy: marker::NoCopy};
2621

2722
fn main() {
28-
test(BAR); //~ ERROR cannot move out of static item
23+
unsafe {
24+
let _f = BAR; //~ ERROR: cannot move out of mutable static item
25+
}
2926
}
27+

src/test/compile-fail/std-uncopyable-atomics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ use std::sync::atomics::*;
1616
use std::ptr;
1717

1818
fn main() {
19-
let x = INIT_ATOMIC_BOOL; //~ ERROR cannot move out of static item
19+
let x = INIT_ATOMIC_BOOL;
2020
let x = *&x; //~ ERROR: cannot move out of dereference
21-
let x = INIT_ATOMIC_INT; //~ ERROR cannot move out of static item
21+
let x = INIT_ATOMIC_INT;
2222
let x = *&x; //~ ERROR: cannot move out of dereference
23-
let x = INIT_ATOMIC_UINT; //~ ERROR cannot move out of static item
23+
let x = INIT_ATOMIC_UINT;
2424
let x = *&x; //~ ERROR: cannot move out of dereference
2525
let x: AtomicPtr<uint> = AtomicPtr::new(ptr::mut_null());
2626
let x = *&x; //~ ERROR: cannot move out of dereference
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Ensure that moves out of statics don't null the static
12+
13+
use std::kinds::marker;
14+
15+
struct Foo {
16+
foo: int,
17+
nocopy: marker::NoCopy
18+
}
19+
20+
impl Eq for Foo {
21+
fn eq(&self, other: &Foo) -> bool {
22+
self.foo == other.foo
23+
}
24+
}
25+
26+
impl std::fmt::Show for Foo {
27+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
28+
write!(f.buf, "Foo({})", self.foo)
29+
}
30+
}
31+
32+
static BAR: Foo = Foo{foo: 5, nocopy: marker::NoCopy};
33+
34+
fn main() {
35+
let x = BAR;
36+
assert_eq!(x, BAR);
37+
}

src/test/compile-fail/borrowck-move-out-of-static-item.rs renamed to src/test/run-pass/borrowck-move-out-of-static-item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Ensure that moves out of static items is forbidden
11+
// Ensure that moves out of immutable static items is allowed
1212

1313
use std::kinds::marker;
1414

@@ -25,5 +25,5 @@ fn test(f: Foo) {
2525
}
2626

2727
fn main() {
28-
test(BAR); //~ ERROR cannot move out of static item
28+
test(BAR);
2929
}

0 commit comments

Comments
 (0)