Immutable static items should be Freeze
Fixes #12432
This commit is contained in:
parent
0c7a0125b4
commit
59a04f5b12
@ -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, _) => {
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
// Verifies all possible restrictions for static items values.
|
||||
|
||||
use std::kinds::marker;
|
||||
|
||||
struct WithDtor;
|
||||
|
||||
impl Drop for WithDtor {
|
||||
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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); }
|
||||
}
|
||||
|
@ -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)()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
#[cfg(target_os="android")]
|
||||
static PROG: &'static str = "ls"; // android don't have echo binary
|
||||
static mut PROG: &'static str = "echo";
|
||||
|
||||
let mut p = Process::new(PROG, []).unwrap();
|
||||
#[cfg(target_os="android")]
|
||||
static mut PROG: &'static str = "ls"; // android don't have echo binary
|
||||
|
||||
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),
|
||||
};
|
||||
@ -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 {
|
||||
@ -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()));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user