Make ~fn non-copyable, make &fn copyable, split barefn/closure types,
correct handling of moves for struct-record update. Part of #3678. Fixes #2828, #3904, #4719.
This commit is contained in:
parent
82d7396333
commit
a32498d846
187 changed files with 2065 additions and 2373 deletions
|
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
#[legacy_modes];
|
||||
#[allow(deprecated_mode)];
|
||||
|
||||
/*!
|
||||
|
||||
|
|
@ -247,8 +248,13 @@ fn pbfs(&&graph: arc::ARC<graph>, key: node_id) -> bfs_result {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_gray_factory() -> ~fn(c: &color) -> bool {
|
||||
let r: ~fn(c: &color) -> bool = is_gray;
|
||||
r
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
while par::any(colors, is_gray) {
|
||||
while par::any(colors, is_gray_factory) {
|
||||
// Do the BFS.
|
||||
log(info, fmt!("PBFS iteration %?", i));
|
||||
i += 1;
|
||||
|
|
@ -257,14 +263,13 @@ fn pbfs(&&graph: arc::ARC<graph>, key: node_id) -> bfs_result {
|
|||
let color = arc::ARC(move colors);
|
||||
|
||||
let color_vec = arc::get(&color); // FIXME #3387 requires this temp
|
||||
colors = do par::mapi_factory(*color_vec) {
|
||||
colors = do par::mapi(*color_vec) {
|
||||
let colors = arc::clone(&color);
|
||||
let graph = arc::clone(&graph);
|
||||
fn~(move graph, move colors, +i: uint, +c: color) -> color {
|
||||
let c : color = c;
|
||||
fn~(+i: uint, +c: &color) -> color {
|
||||
let colors = arc::get(&colors);
|
||||
let graph = arc::get(&graph);
|
||||
match c {
|
||||
match *c {
|
||||
white => {
|
||||
let i = i as node_id;
|
||||
|
||||
|
|
@ -290,11 +295,13 @@ fn pbfs(&&graph: arc::ARC<graph>, key: node_id) -> bfs_result {
|
|||
}
|
||||
|
||||
// Convert the results.
|
||||
do par::map(colors) |c| {
|
||||
match *c {
|
||||
white => { -1i64 }
|
||||
black(parent) => { parent }
|
||||
_ => { die!(~"Found remaining gray nodes in BFS") }
|
||||
do par::map(colors) {
|
||||
fn~(c: &color) -> i64 {
|
||||
match *c {
|
||||
white => { -1i64 }
|
||||
black(parent) => { parent }
|
||||
_ => { die!(~"Found remaining gray nodes in BFS") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -377,14 +384,15 @@ fn validate(edges: ~[(node_id, node_id)],
|
|||
|
||||
log(info, ~"Verifying tree and graph edges...");
|
||||
|
||||
let edges = copy edges;
|
||||
let status = do par::alli(tree) |u, v| {
|
||||
let u = u as node_id;
|
||||
if *v == -1i64 || u == root {
|
||||
true
|
||||
}
|
||||
else {
|
||||
edges.contains(&(u, *v)) || edges.contains(&(*v, u))
|
||||
let status = do par::alli(tree) {
|
||||
let edges = copy edges;
|
||||
fn~(+u: uint, v: &i64) -> bool {
|
||||
let u = u as node_id;
|
||||
if *v == -1i64 || u == root {
|
||||
true
|
||||
} else {
|
||||
edges.contains(&(u, *v)) || edges.contains(&(*v, u))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ extern mod std;
|
|||
use std::list::{List, Cons, Nil};
|
||||
use std::time::precise_time_s;
|
||||
|
||||
enum UniqueList {
|
||||
ULNil, ULCons(~UniqueList)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (repeat, depth) = if os::getenv(~"RUST_BENCH").is_some() {
|
||||
(50, 1000)
|
||||
|
|
@ -43,7 +47,6 @@ struct State {
|
|||
box: @nillist,
|
||||
unique: ~nillist,
|
||||
fn_box: fn@() -> @nillist,
|
||||
fn_unique: fn~() -> ~nillist,
|
||||
tuple: (@nillist, ~nillist),
|
||||
vec: ~[@nillist],
|
||||
res: r
|
||||
|
|
@ -76,7 +79,6 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
|
|||
box: @Nil,
|
||||
unique: ~Nil,
|
||||
fn_box: fn@() -> @nillist { @Nil::<()> },
|
||||
fn_unique: fn~() -> ~nillist { ~Nil::<()> },
|
||||
tuple: (@Nil, ~Nil),
|
||||
vec: ~[@Nil],
|
||||
res: r(@Nil)
|
||||
|
|
@ -84,14 +86,11 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
|
|||
}
|
||||
Some(st) => {
|
||||
let fn_box = st.fn_box;
|
||||
let fn_unique = copy st.fn_unique;
|
||||
|
||||
State {
|
||||
box: @Cons((), st.box),
|
||||
unique: ~Cons((), @*st.unique),
|
||||
fn_box: fn@() -> @nillist { @Cons((), fn_box()) },
|
||||
fn_unique: fn~(move fn_unique) -> ~nillist
|
||||
{ ~Cons((), @*fn_unique()) },
|
||||
tuple: (@Cons((), st.tuple.first()),
|
||||
~Cons((), @*st.tuple.second())),
|
||||
vec: st.vec + ~[@Cons((), st.vec.last())],
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
fn main() {
|
||||
let x = 3;
|
||||
fn blah(_a: extern fn()) {}
|
||||
blah(|| {
|
||||
log(debug, x); //~ ERROR attempted dynamic environment capture
|
||||
});
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
fn to_lambda1(f: fn@(uint) -> uint) -> fn@(uint) -> uint {
|
||||
return f;
|
||||
}
|
||||
|
||||
fn to_lambda2(b: fn(uint) -> uint) -> fn@(uint) -> uint {
|
||||
return to_lambda1(|x| b(x)); //~ ERROR illegal move from argument `b`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
struct Bar {
|
||||
x: int,
|
||||
}
|
||||
|
||||
impl Bar : Drop {
|
||||
fn finalize(&self) {
|
||||
io::println("Goodbye, cruel world");
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
x: int,
|
||||
y: Bar
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Foo { x: 1, y: Bar { x: 5 } };
|
||||
let c = Foo { x: 4, .. a}; //~ ERROR cannot copy field `y` of base expression, which has a noncopyable type
|
||||
io::println(fmt!("%?", c));
|
||||
}
|
||||
|
||||
|
|
@ -8,12 +8,13 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: Non-function passed to a `do` function as its last argument, or wrong number of arguments passed to a `do` function
|
||||
fn main() {
|
||||
let needlesArr: ~[char] = ~['a', 'f'];
|
||||
do vec::foldr(needlesArr) |x, y| {
|
||||
//~^ ERROR 2 parameters were supplied (including the closure passed by the `do` keyword)
|
||||
//~^^ ERROR Unconstrained region variable #2
|
||||
//
|
||||
// this last error is, um, non-ideal.
|
||||
}
|
||||
// for some reason if I use the new error syntax for the two error messages this generates,
|
||||
// the test runner gets confused -- tjc
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ fn main() {
|
|||
copy2(@&x); //~ ERROR missing `&static`
|
||||
|
||||
copy2(fn@() {});
|
||||
copy2(fn~() {}); //~ WARNING instantiating copy type parameter with a not implicitly copyable type
|
||||
copy2(fn&() {}); //~ ERROR missing `copy &static`
|
||||
copy2(fn~() {}); //~ ERROR missing `copy`
|
||||
copy2(fn&() {}); //~ ERROR missing `&static`
|
||||
}
|
||||
|
|
|
|||
27
src/test/compile-fail/moves-sru-moved-field.rs
Normal file
27
src/test/compile-fail/moves-sru-moved-field.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
type Noncopyable = ~fn();
|
||||
|
||||
struct Foo {
|
||||
copied: int,
|
||||
moved: ~int,
|
||||
noncopyable: Noncopyable
|
||||
}
|
||||
|
||||
fn test0(f: Foo, g: Noncopyable, h: Noncopyable) {
|
||||
// just copy implicitly copyable fields from `f`, no moves:
|
||||
let _b = Foo {moved: ~1, noncopyable: g, ..f};
|
||||
let _c = Foo {moved: ~2, noncopyable: h, ..f};
|
||||
}
|
||||
|
||||
fn test1(f: Foo, g: Noncopyable, h: Noncopyable) {
|
||||
// copying move-by-default fields from `f`, so move:
|
||||
let _b = Foo {noncopyable: g, ..f};
|
||||
let _c = Foo {noncopyable: h, ..f}; //~ ERROR use of moved value: `f`
|
||||
}
|
||||
|
||||
fn test2(f: Foo, g: Noncopyable) {
|
||||
// move non-copyable field
|
||||
let _b = Foo {copied: 22, moved: ~23, ..f};
|
||||
let _c = Foo {noncopyable: g, ..f}; //~ ERROR use of moved value: `f`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
fn ignore<T>(_x: T) {}
|
||||
|
||||
pub fn main() {
|
||||
let f: fn@:Owned() = ||();
|
||||
ignore(f);
|
||||
}
|
||||
|
||||
|
|
@ -29,11 +29,11 @@ fn calllink08() { unsafe { rustrt::get_task_id(); } }
|
|||
fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
|
||||
fn calllink10() { unsafe { rustrt::rust_get_task(); } }
|
||||
|
||||
fn runtest(f: fn~(), frame_backoff: u32) {
|
||||
fn runtest(f: extern fn(), frame_backoff: u32) {
|
||||
runtest2(f, frame_backoff, 0 as *u8);
|
||||
}
|
||||
|
||||
fn runtest2(f: fn~(), frame_backoff: u32, last_stk: *u8) -> u32 {
|
||||
fn runtest2(f: extern fn(), frame_backoff: u32, last_stk: *u8) -> u32 {
|
||||
unsafe {
|
||||
let curr_stk = rustrt::debug_get_stk_seg();
|
||||
if (last_stk != curr_stk && last_stk != 0 as *u8) {
|
||||
|
|
@ -67,6 +67,6 @@ pub fn main() {
|
|||
let f = *f;
|
||||
let sz = rng.next() % 256u32 + 256u32;
|
||||
let frame_backoff = rng.next() % 10u32 + 1u32;
|
||||
task::try(|move f| runtest(f, frame_backoff) );
|
||||
task::try(|| runtest(f, frame_backoff) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,5 +16,6 @@ fn compute(i: mytype) -> int { return i.val + 20; }
|
|||
|
||||
pub fn main() {
|
||||
let myval = mytype(Mytype{compute: compute, val: 30});
|
||||
io::println(fmt!("%d", compute(myval)));
|
||||
assert ((myval.compute)(myval) == 50);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright 2012 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.
|
||||
|
||||
pub fn main() { test05(); }
|
||||
|
||||
fn mk_counter<A:Copy>() -> fn~(A) -> (A,uint) {
|
||||
// The only reason that the counter is generic is so that it closes
|
||||
// over both a type descriptor and some data.
|
||||
let v = ~[mut 0u];
|
||||
return fn~(a: A) -> (A,uint) {
|
||||
let n = v[0];
|
||||
v[0] = n + 1u;
|
||||
(a, n)
|
||||
};
|
||||
}
|
||||
|
||||
fn test05() {
|
||||
let fp0 = mk_counter::<float>();
|
||||
|
||||
assert (5.3f, 0u) == fp0(5.3f);
|
||||
assert (5.5f, 1u) == fp0(5.5f);
|
||||
|
||||
let fp1 = copy fp0;
|
||||
|
||||
assert (5.3f, 2u) == fp0(5.3f);
|
||||
assert (5.3f, 2u) == fp1(5.3f);
|
||||
assert (5.5f, 3u) == fp0(5.5f);
|
||||
assert (5.5f, 3u) == fp1(5.5f);
|
||||
}
|
||||
|
|
@ -28,11 +28,11 @@ fn checktests() {
|
|||
// Pull the tests out of the secreturn test module
|
||||
let tests = __test::tests();
|
||||
|
||||
let shouldignore = option::get(
|
||||
vec::find(tests, |t| t.name == ~"shouldignore" ));
|
||||
assert shouldignore.ignore == true;
|
||||
assert vec::any(
|
||||
tests,
|
||||
|t| t.desc.name == ~"shouldignore" && t.desc.ignore);
|
||||
|
||||
let shouldnotignore = option::get(
|
||||
vec::find(tests, |t| t.name == ~"shouldnotignore" ));
|
||||
assert shouldnotignore.ignore == false;
|
||||
assert vec::any(
|
||||
tests,
|
||||
|t| t.desc.name == ~"shouldnotignore" && !t.desc.ignore);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue