Skip to content

Commit 0682ad0

Browse files
committed
Finalize moves-based-on-type implementation.
Changes: - Refactor move mode computation - Removes move mode arguments, unary move, capture clauses (though they still parse for backwards compatibility) - Simplify how moves are handled in trans - Fix a number of illegal copies that cropped up - Workaround for bug involving def-ids in params (see details below) Future work (I'll open bugs for these...): - Improve error messages for moves that are due to bindings - Add support for moving owned content like a.b.c to borrow check, test in trans (but I think it'll "just work") - Proper fix for def-ids in params Def ids in params: Move captures into a map instead of recomputing. This is a workaround for a larger bug having to do with the def-ids associated with ty_params, which are not always properly preserved when inlining. I am not sure of my preferred fix for the larger bug yet. This current fix removes the only code in trans that I know of which relies on ty_param def-ids, but feels fragile.
1 parent 42b462e commit 0682ad0

File tree

125 files changed

+2685
-2644
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+2685
-2644
lines changed

doc/rust.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ For example:
12341234

12351235
~~~~
12361236
trait Num {
1237-
static pure fn from_int(n: int) -> self;
1237+
static pure fn from_int(n: int) -> Self;
12381238
}
12391239
impl float: Num {
12401240
static pure fn from_int(n: int) -> float { n as float }

doc/tutorial-tasks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,8 @@ Finally, tasks can be configured to not propagate failure to each
440440
other at all, using `task::spawn_unlinked` for _isolated failure_.
441441

442442
~~~
443-
# fn random() -> int { 100 }
444-
# fn sleep_for(i: int) { for i.times { task::yield() } }
443+
# fn random() -> uint { 100 }
444+
# fn sleep_for(i: uint) { for i.times { task::yield() } }
445445
# do task::try::<()> {
446446
let (time1, time2) = (random(), random());
447447
do task::spawn_unlinked {

src/etc/tidy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def do_license_check(name, contents):
5151
report_err("TODO is deprecated; use FIXME")
5252
idx = line.find("// NOTE")
5353
if idx != -1:
54-
report_warn("NOTE:" + line[idx + len("// NOTE"):])
54+
report_warn("NOTE" + line[idx + len("// NOTE"):])
5555
if (line.find('\t') != -1 and
5656
fileinput.filename().find("Makefile") == -1):
5757
report_err("tab character")

src/libcargo/cargo.rc

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,19 +1965,17 @@ pub fn main() {
19651965
c = configure(o);
19661966
}
19671967

1968-
let c = &move c;
1969-
19701968
match o.free[1] {
1971-
~"init" => cmd_init(c),
1972-
~"install" => cmd_install(c),
1973-
~"uninstall" => cmd_uninstall(c),
1974-
~"list" => cmd_list(c),
1975-
~"search" => cmd_search(c),
1976-
~"sources" => cmd_sources(c),
1969+
~"init" => cmd_init(&c),
1970+
~"install" => cmd_install(&c),
1971+
~"uninstall" => cmd_uninstall(&c),
1972+
~"list" => cmd_list(&c),
1973+
~"search" => cmd_search(&c),
1974+
~"sources" => cmd_sources(&c),
19771975
_ => cmd_usage()
19781976
}
19791977

1980-
dump_cache(c);
1981-
dump_sources(c);
1978+
dump_cache(&c);
1979+
dump_sources(&c);
19821980
}
19831981

src/libcore/private/global.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,10 @@ fn get_global_state() -> Exclusive<GlobalState> {
177177
let state = ~exclusive(state);
178178

179179
// Convert it to an integer
180-
let state_ptr: &Exclusive<GlobalState> = state;
181-
let state_i: int = unsafe { transmute(state_ptr) };
180+
let state_i: int = unsafe {
181+
let state_ptr: &Exclusive<GlobalState> = state;
182+
transmute(state_ptr)
183+
};
182184

183185
// Swap our structure into the global pointer
184186
let prev_i = unsafe { atomic_cxchg(&mut *global_ptr, 0, state_i) };

src/libcore/task/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,12 +836,20 @@ fn test_run_basic() {
836836
po.recv();
837837
}
838838

839+
#[test]
840+
struct Wrapper {
841+
mut f: Option<Chan<()>>
842+
}
843+
839844
#[test]
840845
fn test_add_wrapper() {
841846
let (po, ch) = stream::<()>();
842847
let b0 = task();
848+
let ch = Wrapper { f: Some(ch) };
843849
let b1 = do b0.add_wrapper |body| {
850+
let ch = Wrapper { f: Some(ch.f.swap_unwrap()) };
844851
fn~(move body) {
852+
let ch = ch.f.swap_unwrap();
845853
body();
846854
ch.send(());
847855
}
@@ -929,9 +937,12 @@ fn test_spawn_sched_childs_on_default_sched() {
929937
// Assuming tests run on the default scheduler
930938
let default_id = unsafe { rt::rust_get_sched_id() };
931939

940+
let ch = Wrapper { f: Some(ch) };
932941
do spawn_sched(SingleThreaded) {
933942
let parent_sched_id = unsafe { rt::rust_get_sched_id() };
943+
let ch = Wrapper { f: Some(ch.f.swap_unwrap()) };
934944
do spawn {
945+
let ch = ch.f.swap_unwrap();
935946
let child_sched_id = unsafe { rt::rust_get_sched_id() };
936947
assert parent_sched_id != child_sched_id;
937948
assert child_sched_id == default_id;

src/librustc/back/rpath.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
191191
let mut minimized = ~[];
192192
for rpaths.each |rpath| {
193193
let s = rpath.to_str();
194-
if !set.contains_key(s) {
194+
if !set.contains_key_ref(&s) {
195195
minimized.push(/*bad*/copy *rpath);
196196
set.insert(s, ());
197197
}

src/librustc/driver/driver.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use front;
1616
use lib::llvm::llvm;
1717
use metadata::{creader, cstore, filesearch};
1818
use metadata;
19-
use middle::{trans, freevars, kind, ty, typeck, lint};
19+
use middle::{trans, freevars, kind, ty, typeck, lint, astencode};
2020
use middle;
2121
use session::{Session, Session_, OptLevel, No, Less, Default, Aggressive};
2222
use session;
@@ -281,20 +281,26 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg,
281281
time(time_passes, ~"loop checking", ||
282282
middle::check_loop::check_crate(ty_cx, crate));
283283

284-
time(time_passes, ~"mode computation", ||
285-
middle::mode::compute_modes(ty_cx, method_map, crate));
284+
let middle::moves::MoveMaps {moves_map, variable_moves_map,
285+
capture_map} =
286+
time(time_passes, ~"compute moves", ||
287+
middle::moves::compute_moves(ty_cx, method_map, crate));
286288

287289
time(time_passes, ~"match checking", ||
288-
middle::check_match::check_crate(ty_cx, method_map, crate));
290+
middle::check_match::check_crate(ty_cx, method_map,
291+
moves_map, crate));
289292

290293
let last_use_map =
291294
time(time_passes, ~"liveness checking", ||
292-
middle::liveness::check_crate(ty_cx, method_map, crate));
295+
middle::liveness::check_crate(ty_cx, method_map,
296+
variable_moves_map,
297+
capture_map, crate));
293298

294299
let (root_map, mutbl_map, write_guard_map) =
295300
time(time_passes, ~"borrow checking", ||
296301
middle::borrowck::check_crate(ty_cx, method_map,
297-
last_use_map, crate));
302+
moves_map, capture_map,
303+
crate));
298304

299305
time(time_passes, ~"kind checking", ||
300306
kind::check_crate(ty_cx, method_map, last_use_map, crate));
@@ -304,12 +310,16 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg,
304310

305311
if upto == cu_no_trans { return {crate: crate, tcx: Some(ty_cx)}; }
306312

307-
let maps = {mutbl_map: mutbl_map,
308-
root_map: root_map,
309-
last_use_map: last_use_map,
310-
method_map: method_map,
311-
vtable_map: vtable_map,
312-
write_guard_map: write_guard_map};
313+
let maps = astencode::Maps {
314+
mutbl_map: mutbl_map,
315+
root_map: root_map,
316+
last_use_map: last_use_map,
317+
method_map: method_map,
318+
vtable_map: vtable_map,
319+
write_guard_map: write_guard_map,
320+
moves_map: moves_map,
321+
capture_map: capture_map
322+
};
313323

314324
time(time_passes, ~"translation", ||
315325
trans::base::trans_crate(sess, crate, ty_cx,
@@ -528,7 +538,7 @@ pub fn build_session_options(+binary: ~str,
528538
getopts::opt_strs(matches, level_name));
529539
for flags.each |lint_name| {
530540
let lint_name = str::replace(*lint_name, ~"-", ~"_");
531-
match lint_dict.find(lint_name) {
541+
match lint_dict.find(/*bad*/ copy lint_name) {
532542
None => {
533543
early_error(demitter, fmt!("unknown %s flag: %s",
534544
level_name, lint_name));

src/librustc/front/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub fn metas_in_cfg(cfg: ast::crate_cfg,
190190
if !has_cfg_metas { return true; }
191191

192192
for cfg_metas.each |cfg_mi| {
193-
if attr::contains(/*bad*/copy cfg, *cfg_mi) { return true; }
193+
if attr::contains(cfg, *cfg_mi) { return true; }
194194
}
195195

196196
return false;

src/librustc/front/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn modify_for_testing(sess: session::Session,
4646
// We generate the test harness when building in the 'test'
4747
// configuration, either with the '--test' or '--cfg test'
4848
// command line options.
49-
let should_test = attr::contains(/*bad*/copy crate.node.config,
49+
let should_test = attr::contains(crate.node.config,
5050
attr::mk_word_item(~"test"));
5151

5252
if should_test {
@@ -510,7 +510,7 @@ fn mk_test_wrapper(cx: test_ctxt,
510510
let wrapper_expr = ast::expr {
511511
id: cx.sess.next_node_id(),
512512
callee_id: cx.sess.next_node_id(),
513-
node: ast::expr_fn(ast::ProtoBare, wrapper_decl, wrapper_body, @~[]),
513+
node: ast::expr_fn(ast::ProtoBare, wrapper_decl, wrapper_body),
514514
span: span
515515
};
516516

src/librustc/lib/llvm.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,23 +1344,22 @@ pub fn mk_type_names() -> type_names {
13441344
}
13451345

13461346
pub fn type_to_str(names: type_names, ty: TypeRef) -> @str {
1347-
return type_to_str_inner(names, ~[], ty);
1347+
return type_to_str_inner(names, [], ty);
13481348
}
13491349

1350-
pub fn type_to_str_inner(names: type_names, +outer0: ~[TypeRef], ty: TypeRef)
1350+
pub fn type_to_str_inner(names: type_names, +outer0: &[TypeRef], ty: TypeRef)
13511351
-> @str {
13521352
unsafe {
13531353
match type_has_name(names, ty) {
13541354
option::Some(n) => return n,
13551355
_ => {}
13561356
}
13571357

1358-
// FIXME #2543: Bad copy.
1359-
let outer = vec::append_one(copy outer0, ty);
1358+
let outer = vec::append_one(outer0.to_vec(), ty);
13601359

13611360
let kind = llvm::LLVMGetTypeKind(ty);
13621361

1363-
fn tys_str(names: type_names, outer: ~[TypeRef],
1362+
fn tys_str(names: type_names, outer: &[TypeRef],
13641363
tys: ~[TypeRef]) -> @str {
13651364
let mut s = ~"";
13661365
let mut first: bool = true;

src/librustc/metadata/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
133133
tag_table_vtable_map = 0x61,
134134
tag_table_adjustments = 0x62,
135135
tag_table_legacy_boxed_trait = 0x63,
136-
tag_table_value_mode = 0x64
136+
tag_table_moves_map = 0x64,
137+
tag_table_capture_map = 0x65
137138
}
138139

139140
pub const tag_item_trait_method_sort: uint = 0x70;

src/librustc/metadata/creader.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ fn visit_item(e: env, i: @ast::item) {
163163
None => /*bad*/copy *e.intr.get(i.ident)
164164
};
165165
if attr::find_attrs_by_name(i.attrs, ~"nolink").is_empty() {
166-
already_added = !cstore::add_used_library(cstore,
167-
foreign_name);
166+
already_added =
167+
!cstore::add_used_library(cstore, copy foreign_name);
168168
}
169169
if !link_args.is_empty() && already_added {
170170
e.diag.span_fatal(i.span, ~"library '" + foreign_name +
@@ -281,7 +281,8 @@ fn resolve_crate_deps(e: env, cdata: @~[u8]) -> cstore::cnum_map {
281281
let cmetas = metas_with(/*bad*/copy dep.vers, ~"vers", ~[]);
282282
debug!("resolving dep crate %s ver: %s hash: %s",
283283
*e.intr.get(dep.name), dep.vers, dep.hash);
284-
match existing_match(e, metas_with_ident(*e.intr.get(cname), cmetas),
284+
match existing_match(e, metas_with_ident(copy *e.intr.get(cname),
285+
copy cmetas),
285286
dep.hash) {
286287
Some(local_cnum) => {
287288
debug!("already have it");

src/librustc/metadata/encoder.rs

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -648,14 +648,22 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: writer::Encoder,
648648
/* Encode the dtor */
649649
do struct_def.dtor.iter |dtor| {
650650
index.push({val: dtor.node.id, pos: ebml_w.writer.tell()});
651-
encode_info_for_ctor(ecx, ebml_w, dtor.node.id,
651+
encode_info_for_ctor(ecx,
652+
ebml_w,
653+
dtor.node.id,
652654
ecx.tcx.sess.ident_of(
653655
ecx.tcx.sess.str_of(item.ident) +
654656
~"_dtor"),
655-
path, if tps.len() > 0u {
656-
Some(ii_dtor(*dtor, item.ident, tps,
657+
path,
658+
if tps.len() > 0u {
659+
Some(ii_dtor(copy *dtor,
660+
item.ident,
661+
copy tps,
657662
local_def(item.id))) }
658-
else { None }, tps);
663+
else {
664+
None
665+
},
666+
tps);
659667
}
660668

661669
/* Index the class*/
@@ -869,27 +877,35 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: writer::Encoder,
869877
syntax::parse::token::special_idents::invalid);
870878
visit::visit_crate(*crate, (), visit::mk_vt(@visit::Visitor {
871879
visit_expr: |_e, _cx, _v| { },
872-
visit_item: |i, cx, v, copy ebml_w| {
873-
visit::visit_item(i, cx, v);
874-
match ecx.tcx.items.get(i.id) {
875-
ast_map::node_item(_, pt) => {
876-
encode_info_for_item(ecx, ebml_w, i, index, *pt);
877-
}
878-
_ => fail ~"bad item"
880+
visit_item: {
881+
let ebml_w = copy ebml_w;
882+
|i, cx, v| {
883+
visit::visit_item(i, cx, v);
884+
match ecx.tcx.items.get(i.id) {
885+
ast_map::node_item(_, pt) => {
886+
encode_info_for_item(ecx, ebml_w, i,
887+
index, *pt);
888+
}
889+
_ => fail ~"bad item"
890+
}
879891
}
880892
},
881-
visit_foreign_item: |ni, cx, v, copy ebml_w| {
882-
visit::visit_foreign_item(ni, cx, v);
883-
match ecx.tcx.items.get(ni.id) {
884-
ast_map::node_foreign_item(_, abi, pt) => {
885-
encode_info_for_foreign_item(ecx, ebml_w, ni,
886-
index, /*bad*/copy *pt, abi);
887-
}
888-
// case for separate item and foreign-item tables
889-
_ => fail ~"bad foreign item"
893+
visit_foreign_item: {
894+
let ebml_w = copy ebml_w;
895+
|ni, cx, v| {
896+
visit::visit_foreign_item(ni, cx, v);
897+
match ecx.tcx.items.get(ni.id) {
898+
ast_map::node_foreign_item(_, abi, pt) => {
899+
encode_info_for_foreign_item(ecx, ebml_w, ni,
900+
index, /*bad*/copy *pt,
901+
abi);
902+
}
903+
// case for separate item and foreign-item tables
904+
_ => fail ~"bad foreign item"
905+
}
890906
}
891-
}
892-
,.. *visit::default_visitor()
907+
},
908+
..*visit::default_visitor()
893909
}));
894910
ebml_w.end_tag();
895911
return /*bad*/copy *index;

src/librustc/metadata/loader.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ pub fn note_linkage_attrs(intr: @ident_interner, diag: span_handler,
165165
}
166166
}
167167

168-
fn crate_matches(crate_data: @~[u8], +metas: ~[@ast::meta_item],
168+
fn crate_matches(crate_data: @~[u8],
169+
metas: &[@ast::meta_item],
169170
hash: ~str) -> bool {
170171
let attrs = decoder::get_crate_attributes(crate_data);
171172
let linkage_metas = attr::find_linkage_metas(attrs);
@@ -177,7 +178,7 @@ fn crate_matches(crate_data: @~[u8], +metas: ~[@ast::meta_item],
177178
}
178179

179180
pub fn metadata_matches(extern_metas: ~[@ast::meta_item],
180-
local_metas: ~[@ast::meta_item]) -> bool {
181+
local_metas: &[@ast::meta_item]) -> bool {
181182

182183
debug!("matching %u metadata requirements against %u items",
183184
vec::len(local_metas), vec::len(extern_metas));

src/librustc/metadata/tydecode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
275275
}
276276
'p' => {
277277
let did = parse_def(st, TypeParameter, conv);
278+
debug!("parsed ty_param: did=%?", did);
278279
return ty::mk_param(st.tcx, parse_int(st) as uint, did);
279280
}
280281
's' => {
@@ -422,7 +423,6 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
422423

423424
fn parse_mode(st: @pstate) -> ast::mode {
424425
let m = ast::expl(match next(st) {
425-
'-' => ast::by_move,
426426
'+' => ast::by_copy,
427427
'=' => ast::by_ref,
428428
'#' => ast::by_val,

src/librustc/metadata/tyencode.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ pub fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) {
342342

343343
pub fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) {
344344
match ty::resolved_mode(cx.tcx, m) {
345-
by_move => w.write_char('-'),
346345
by_copy => w.write_char('+'),
347346
by_ref => w.write_char('='),
348347
by_val => w.write_char('#')

0 commit comments

Comments
 (0)