Skip to content

Commit

Permalink
Immutable static items should be Freeze Fixes rust-lang#12432
Browse files Browse the repository at this point in the history
  • Loading branch information
flaper87 committed Feb 27, 2014
1 parent 0c7a012 commit 59a04f5
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 18 deletions.
21 changes: 21 additions & 0 deletions src/librustc/middle/check_static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,24 @@ impl Visitor<bool> for CheckStaticVisitor {
self.tcx.sess.span_err(e.span,
"static items are not allowed to have owned pointers");
}
ast::ExprProc(..) => {
self.report_error(e.span,
Some(~"immutable static items must be `Freeze`"));
return;
}
ast::ExprAddrOf(mutability, _) => {
match mutability {
ast::MutMutable => {
self.report_error(e.span,
Some(~"immutable static items must be `Freeze`"));
return;
}
_ => {}
}
}
_ => {
let node_ty = ty::node_id_to_type(self.tcx, e.id);

match ty::get(node_ty).sty {
ty::ty_struct(did, _) |
ty::ty_enum(did, _) => {
Expand All @@ -128,6 +144,11 @@ impl Visitor<bool> for CheckStaticVisitor {
Some(~"static items are not allowed to have destructors"));
return;
}
if Some(did) == self.tcx.lang_items.no_freeze_bound() {
self.report_error(e.span,
Some(~"immutable static items must be `Freeze`"));
return;
}
}
_ => {}
}
Expand Down
26 changes: 26 additions & 0 deletions src/test/compile-fail/check-static-values-constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

// Verifies all possible restrictions for static items values.

use std::kinds::marker;

struct WithDtor;

impl Drop for WithDtor {
Expand Down Expand Up @@ -122,6 +124,30 @@ static STATIC18: @SafeStruct = @SafeStruct{field1: Variant1, field2: Variant2(0)
static STATIC19: ~int = box 3;
//~^ ERROR static items are not allowed to have owned pointers


struct StructNoFreeze<'a> {
nf: &'a int
}

enum EnumNoFreeze<'a> {
FreezableVariant,
NonFreezableVariant(StructNoFreeze<'a>)
}

static STATIC20: StructNoFreeze<'static> = StructNoFreeze{nf: &'static mut 4};
//~^ ERROR immutable static items must be `Freeze`

static STATIC21: EnumNoFreeze<'static> = FreezableVariant;
static STATIC22: EnumNoFreeze<'static> = NonFreezableVariant(StructNoFreeze{nf: &'static mut 4});
//~^ ERROR immutable static items must be `Freeze`

struct NFMarker {
nf: marker::NoFreeze
}

static STATIC23: NFMarker = NFMarker{nf: marker::NoFreeze};
//~^ ERROR immutable static items must be `Freeze`

pub fn main() {
let y = { static x: ~int = ~3; x };
//~^ ERROR static items are not allowed to have owned pointers
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/static-mut-not-constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

static mut a: ~int = ~3; //~ ERROR: cannot do allocations in constant expressions
static mut a: ~int = ~3; //~ ERROR: mutable static items are not allowed to have owned pointers

fn main() {}
4 changes: 2 additions & 2 deletions src/test/run-pass/const-fn-val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ fn foo() -> int {

struct Bar<'a> { f: 'a || -> int }

static b : Bar<'static> = Bar { f: foo };
static mut b : Bar<'static> = Bar { f: foo };

pub fn main() {
assert_eq!((b.f)(), 0xca7f000d);
unsafe { assert_eq!((b.f)(), 0xca7f000d); }
}
12 changes: 7 additions & 5 deletions src/test/run-pass/const-vec-of-fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
fn f() { }
static bare_fns: &'static [fn()] = &[f, f];
struct S<'a>('a ||);
static closures: &'static [S<'static>] = &[S(f), S(f)];
static mut closures: &'static [S<'static>] = &[S(f), S(f)];

pub fn main() {
for &bare_fn in bare_fns.iter() { bare_fn() }
for closure in closures.iter() {
let S(ref closure) = *closure;
(*closure)()
unsafe {
for &bare_fn in bare_fns.iter() { bare_fn() }
for closure in closures.iter() {
let S(ref closure) = *closure;
(*closure)()
}
}
}
21 changes: 11 additions & 10 deletions src/test/run-pass/core-run-destroy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,23 @@ use std::io::process::{Process, ProcessOutput};
#[test]
fn test_destroy_once() {
#[cfg(not(target_os="android"))]
static PROG: &'static str = "echo";
static mut PROG: &'static str = "echo";

#[cfg(target_os="android")]
static PROG: &'static str = "ls"; // android don't have echo binary
static mut PROG: &'static str = "ls"; // android don't have echo binary

let mut p = Process::new(PROG, []).unwrap();
let mut p = unsafe {Process::new(PROG, []).unwrap()};
p.signal_exit().unwrap(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
#[cfg(not(target_os="android"))]
static PROG: &'static str = "echo";
static mut PROG: &'static str = "echo";
#[cfg(target_os="android")]
static PROG: &'static str = "ls"; // android don't have echo binary
static mut PROG: &'static str = "ls"; // android don't have echo binary

let mut p = match Process::new(PROG, []) {
let mut p = match unsafe{Process::new(PROG, [])} {
Ok(p) => p,
Err(e) => fail!("wut: {}", e),
};
Expand All @@ -49,13 +50,13 @@ fn test_destroy_twice() {
fn test_destroy_actually_kills(force: bool) {

#[cfg(unix,not(target_os="android"))]
static BLOCK_COMMAND: &'static str = "cat";
static mut BLOCK_COMMAND: &'static str = "cat";

#[cfg(unix,target_os="android")]
static BLOCK_COMMAND: &'static str = "/system/bin/cat";
static mut BLOCK_COMMAND: &'static str = "/system/bin/cat";

#[cfg(windows)]
static BLOCK_COMMAND: &'static str = "cmd";
static mut BLOCK_COMMAND: &'static str = "cmd";

#[cfg(unix,not(target_os="android"))]
fn process_exists(pid: libc::pid_t) -> bool {
Expand Down Expand Up @@ -91,7 +92,7 @@ fn test_destroy_actually_kills(force: bool) {
}

// this process will stay alive indefinitely trying to read from stdin
let mut p = Process::new(BLOCK_COMMAND, []).unwrap();
let mut p = unsafe {Process::new(BLOCK_COMMAND, []).unwrap()};

assert!(process_exists(p.id()));

Expand Down

5 comments on commit 59a04f5

@nikomatsakis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

Please sign in to comment.