diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs index a8fea66b192..a33f05a95f6 100644 --- a/src/cargo/cargo.rs +++ b/src/cargo/cargo.rs @@ -165,7 +165,8 @@ fn test_is_uuid() { assert !is_uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaป"); } -// FIXME: implement url/URL parsing so we don't have to resort to weak checks +// FIXME (#2661): implement url/URL parsing so we don't have to resort +// to weak checks fn has_archive_extension(p: str) -> bool { str::ends_with(p, ".tar") || @@ -188,8 +189,8 @@ fn is_archive_path(u: str) -> bool { } fn is_archive_url(u: str) -> bool { - // FIXME: this requires the protocol bit - if we had proper url parsing, - // we wouldn't need it + // FIXME (#2661): this requires the protocol bit - if we had proper + // url parsing, we wouldn't need it alt str::find_str(u, "://") { option::some(i) { has_archive_extension(u) } @@ -315,7 +316,7 @@ fn load_crate(filename: str) -> option { alt *attr_name { "std" | "core" { } - _ { e.deps += [query]; } + _ { vec::push(e.deps, query); } } } _ { } @@ -774,7 +775,7 @@ fn install_source(c: cargo, path: str) { let mut cratefiles = []; for os::walk_dir(".") {|p| if str::ends_with(p, ".rc") { - cratefiles += [p]; + vec::push(cratefiles, p); } } @@ -956,9 +957,10 @@ fn cmd_uninstall(c: cargo) { let bin = c.bindir; let target = c.opts.free[2u]; - // FIXME: needs stronger pattern matching - // FIXME: needs to uninstall from a specified location in a cache instead - // of looking for it (binaries can be uninstalled by name only) + // FIXME (#2662): needs stronger pattern matching + // FIXME (#2662): needs to uninstall from a specified location in a + // cache instead of looking for it (binaries can be uninstalled by + // name only) if is_uuid(target) { for os::list_dir(lib).each { |file| alt str::find_str(file, "-" + target + "-") { @@ -1059,8 +1061,8 @@ fn install_query(c: cargo, wd: str, target: str) { } } - // FIXME: This whole dep_cache and current_install - // thing is a bit of a hack. It should be cleaned up in the future. + // FIXME (#2662): This whole dep_cache and current_install thing is + // a bit of a hack. It should be cleaned up in the future. if target == c.current_install { for c.dep_cache.each { |k, _v| @@ -1894,7 +1896,7 @@ fn main(argv: [str]) { if !first_time && o.free[1] != "init" { cmd_init(c); - // FIXME: shouldn't need to reconfigure + // FIXME (#2662): shouldn't need to reconfigure c = configure(o); } diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 079fba0ba65..06428a993d2 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -139,7 +139,7 @@ fn make_tests(config: config) -> [test::test_desc] { let file = file; #debug("inspecting file %s", file); if is_test(config, file) { - tests += [make_test(config, file)] + vec::push(tests, make_test(config, file)) } } ret tests; diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 3c33aec270f..642e2073e6b 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -31,7 +31,7 @@ fn load_props(testfile: str) -> test_props { let mut pp_exact = option::none; for iter_header(testfile) {|ln| alt parse_error_pattern(ln) { - option::some(ep) { error_patterns += [ep]; } + option::some(ep) { vec::push(error_patterns, ep) } option::none { } }; @@ -44,11 +44,11 @@ fn load_props(testfile: str) -> test_props { } option::iter(parse_aux_build(ln)) {|ab| - aux_builds += [ab]; + vec::push(aux_builds, ab); } option::iter(parse_exec_env(ln)) {|ee| - exec_env += [ee]; + vec::push(exec_env, ee); } }; ret { diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 1d8096042b3..354d966c2cc 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -19,7 +19,7 @@ fn target_env(lib_path: str, prog: str) -> [(str,str)] { else { (k,v) } }; if str::ends_with(prog, "rustc.exe") { - env += [("RUST_THREADS", "1")] + vec::push(env, ("RUST_THREADS", "1")); } ret env; } @@ -32,7 +32,7 @@ fn target_env(_lib_path: str, _prog: str) -> [(str,str)] { } -// FIXME: This code is duplicated in core::run::program_output +// FIXME (#2659): This code is duplicated in core::run::program_output fn run(lib_path: str, prog: str, args: [str], diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 5afe663f23b..749af7d9f73 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -104,7 +104,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: str) { procres); } - srcs += [procres.stdout]; + vec::push(srcs, procres.stdout); round += 1; } diff --git a/src/etc/get-snapshot.py b/src/etc/get-snapshot.py index 964c06ffcae..7d390c8c9aa 100755 --- a/src/etc/get-snapshot.py +++ b/src/etc/get-snapshot.py @@ -8,11 +8,7 @@ def unpack_snapshot(triple, dl_path): tar = tarfile.open(dl_path) kernel = get_kernel(triple) for p in tar.getnames(): - - # FIXME: Fix this once win32 snapshot globs are fixed. - name = p.replace("rust-stage0/stage3/", "", 1); - name = name.replace("rust-stage0/", "", 1); - + name = p.replace("rust-stage0/", "", 1); stagep = os.path.join(triple, "stage0") fp = os.path.join(stagep, name) print("extracting " + p) diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 9da9ae6b14d..780ba428209 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -183,7 +183,7 @@ Please make a clean build." % "\n ".join(matches)) shutil.move(file0, file1) if flag == "install": - # FIXME this is an ugly quick hack; pls make it better + # FIXME (#2664): this is an ugly quick hack; pls make it better path = file1 comps = path.split("-") parts = { 'year': comps[2], \ diff --git a/src/etc/tidy.py b/src/etc/tidy.py index a8d87ece989..51e13e7af19 100644 --- a/src/etc/tidy.py +++ b/src/etc/tidy.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import sys, fileinput, subprocess +import sys, fileinput, subprocess, re err=0 cols=78 @@ -23,6 +23,11 @@ file_names = [s for s in sys.argv[1:] if not s.endswith("_gen.rs")] try: for line in fileinput.input(file_names, openhook=fileinput.hook_encoded("utf-8")): + + if fileinput.filename().find("tidy.py") == -1: + if line.find("FIXME") != -1: + if re.search("FIXME.*#\d+", line) == None: + report_err("FIXME without issue number") if (line.find('\t') != -1 and fileinput.filename().find("Makefile") == -1): report_err("tab character") diff --git a/src/fuzzer/cycles.rs b/src/fuzzer/cycles.rs index e604d4a2357..4773a331c13 100644 --- a/src/fuzzer/cycles.rs +++ b/src/fuzzer/cycles.rs @@ -62,7 +62,7 @@ fn test_cycles(r : rand::rng, k: uint, n: uint) // Create a graph with no edges range(0u, vlen) {|_i| - v += [mut empty_pointy()]; + vec::push(v, empty_pointy()); } // Fill in the graph with random edges, with density k/n @@ -77,7 +77,7 @@ fn test_cycles(r : rand::rng, k: uint, n: uint) // https://github.com/mozilla/rust/issues/1899 if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; } - if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; } + if (likelihood(r, k, n)) { vec::push(v[i].n, mut p(choice(r, v))); } if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; } } diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 95abb6636a8..7c59ceeef00 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -129,7 +129,7 @@ fn stash_ty_if(c: fn@(@ast::ty, test_mode)->bool, e: @ast::ty, tm: test_mode) { if c(e, tm) { - *es += [*e]; + vec::push(*es,*e); } else {/* now my indices are wrong :( */ } } diff --git a/src/fuzzer/ivec_fuzz.rs b/src/fuzzer/ivec_fuzz.rs index ed02550bb13..9ea4d888fb2 100644 --- a/src/fuzzer/ivec_fuzz.rs +++ b/src/fuzzer/ivec_fuzz.rs @@ -57,11 +57,11 @@ fn vec_edits(v: [T], xs: [T]) -> [[T]] { if Lv != 1u { // When Lv == 1u, this is redundant with omit. - edits += [[]]; + vec::push(edits, []); } if Lv >= 3u { // When Lv == 2u, this is redundant with swap. - edits += [vec::reversed(v)]; + vec::push(edits, vec::reversed(v)); } ix(0u, 1u, Lv) {|i| edits += [vec_omit(v, i)]; } ix(0u, 1u, Lv) {|i| edits += [vec_dup(v, i)]; } @@ -71,10 +71,10 @@ fn vec_edits(v: [T], xs: [T]) -> [[T]] { ix(0u, 1u, len(xs)) {|j| ix(0u, 1u, Lv) {|i| - edits += [vec_poke(v, i, xs[j])]; + vec::push(edits, vec_poke(v, i, xs[j])); } ix(0u, 0u, Lv) {|i| - edits += [vec_insert(v, i, xs[j])]; + vec::push(edits, vec_insert(v, i, xs[j])); } } diff --git a/src/fuzzer/rand_util.rs b/src/fuzzer/rand_util.rs index 1a51ab0cd41..3f5c00c313f 100644 --- a/src/fuzzer/rand_util.rs +++ b/src/fuzzer/rand_util.rs @@ -62,7 +62,7 @@ fn weighted_vec(v : [weighted]) -> [T] { for {weight: weight, item: item} in v { let i = 0u; while i < weight { - r += [item]; + vec::push(r, item); i += 1u; } } diff --git a/src/libcore/arc.rs b/src/libcore/arc.rs index a6baae0d082..ddbc4e8321f 100644 --- a/src/libcore/arc.rs +++ b/src/libcore/arc.rs @@ -68,17 +68,18 @@ allowing them to share the underlying data."] fn clone(rc: &arc) -> arc { unsafe { let ptr: ~arc_data = unsafe::reinterpret_cast(**rc); - rustrt::rust_atomic_increment(&mut ptr.count); + let new_count = rustrt::rust_atomic_increment(&mut ptr.count); + assert new_count >= 2; unsafe::forget(ptr); } arc_destruct(**rc) } // An arc over mutable data that is protected by a lock. -type ex_data = {lock: sys::lock_and_signal, data: T}; -type exclusive = arc_destruct>; +type ex_data = {lock: sys::lock_and_signal, data: T}; +type exclusive = arc_destruct>; -fn exclusive(-data: T) -> exclusive { +fn exclusive(-data: T) -> exclusive { let data = ~{mut count: 1, data: {lock: sys::create_lock(), data: data}}; unsafe { @@ -88,12 +89,13 @@ fn exclusive(-data: T) -> exclusive { } } -impl methods for exclusive { +impl methods for exclusive { fn clone() -> exclusive { unsafe { // this makes me nervous... let ptr: ~arc_data> = unsafe::reinterpret_cast(*self); - rustrt::rust_atomic_increment(&mut ptr.count); + let new_count = rustrt::rust_atomic_increment(&mut ptr.count); + assert new_count > 1; unsafe::forget(ptr); } arc_destruct(*self) diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs index f0b346e32a3..fbb434d8e4b 100644 --- a/src/libcore/cmath.rs +++ b/src/libcore/cmath.rs @@ -2,8 +2,8 @@ export c_float; export c_double; // uncomment once #1433 is fixed -// FIXME export c_float_math_consts; -// FIXME export c_double_math_consts; +// FIXME (#1433): export c_float_math_consts; +// FIXME (#1433): export c_double_math_consts; export c_float_targ_consts; export c_double_targ_consts; @@ -68,8 +68,7 @@ native mod c_double { #[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int; pure fn modf(n: c_double, &iptr: c_double) -> c_double; pure fn pow(n: c_double, e: c_double) -> c_double; -// FIXME enable when rounding modes become available -// (See Issue #1379) +// FIXME (#1379): enable when rounding modes become available // pure fn rint(n: c_double) -> c_double; pure fn round(n: c_double) -> c_double; // rename: for consistency with logradix @@ -149,8 +148,7 @@ native mod c_float { #[link_name="modff"] pure fn modf(n: c_float, &iptr: c_float) -> c_float; #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float; -// FIXME enable when rounding modes become available -// (See Issue #1379) +// FIXME (#1379): enable when rounding modes become available // #[link_name="rintf"] pure fn rint(n: c_float) -> c_float; #[link_name="roundf"] pure fn round(n: c_float) -> c_float; #[link_name="scalbnf"] pure fn ldexp_radix(n: c_float, i: c_int) @@ -176,8 +174,8 @@ mod c_float_targ_consts { const max_exp: uint = 128u; const min_10_exp: int = -37; const max_10_exp: int = 38; - // FIXME this is wrong! replace with hexadecimal (%a) constants below - // (see Issue #1433) + // FIXME (#1433): this is wrong, replace with hexadecimal (%a) constants + // below. const min_value: f32 = 1.175494e-38_f32; const max_value: f32 = 3.402823e+38_f32; const epsilon: f32 = 0.000000_f32; @@ -191,8 +189,8 @@ mod c_double_targ_consts { const max_exp: uint = 1024u; const min_10_exp: int = -307; const max_10_exp: int = 308; - // FIXME this is wrong! replace with hexadecimal (%a) constants below - // (see Issue #1433) + // FIXME (#1433): this is wrong, replace with hexadecimal (%a) constants + // below. const min_value: f64 = 2.225074e-308_f64; const max_value: f64 = 1.797693e+308_f64; const epsilon: f64 = 2.220446e-16_f64; diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 7c2a9737f04..722c485d72e 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -94,27 +94,29 @@ fn listen(f: fn(chan) -> U) -> U { f(po.chan()) } -resource port_ptr(po: *rust_port) unsafe { +class port_ptr { + let po: *rust_port; + new(po: *rust_port) { self.po = po; } + drop unsafe { task::unkillable {|| // Once the port is detached it's guaranteed not to receive further // messages let yield = 0u; let yieldp = ptr::addr_of(yield); - rustrt::rust_port_begin_detach(po, yieldp); + rustrt::rust_port_begin_detach(self.po, yieldp); if yield != 0u { // Need to wait for the port to be detached - // FIXME: If this fails then we're going to leave our port - // in a bogus state. (Issue #1988) task::yield(); } - rustrt::rust_port_end_detach(po); + rustrt::rust_port_end_detach(self.po); // Drain the port so that all the still-enqueued items get dropped - while rustrt::rust_port_size(po) > 0u as size_t { - recv_::(po); + while rustrt::rust_port_size(self.po) > 0u as size_t { + recv_::(self.po); } - rustrt::del_port(po); + rustrt::del_port(self.po); } + } } #[doc = " @@ -126,21 +128,26 @@ Fails if the port is detached or dead. Fails if the port is owned by a different task. "] fn as_raw_port(ch: comm::chan, f: fn(*rust_port) -> U) -> U { - resource portref(p: *rust_port) { - if !ptr::is_null(p) { - rustrt::rust_port_drop(p); - } + + class portref { + let p: *rust_port; + new(p: *rust_port) { self.p = p; } + drop { + if !ptr::is_null(self.p) { + rustrt::rust_port_drop(self.p); + } + } } let p = portref(rustrt::rust_port_take(*ch)); - if ptr::is_null(*p) { + if ptr::is_null(p.p) { fail "unable to locate port for channel" - } else if rustrt::get_task_id() != rustrt::rust_port_task(*p) { + } else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) { fail "unable to access unowned port" } - f(*p) + f(p.p) } #[doc = " @@ -148,7 +155,7 @@ Constructs a channel. The channel is bound to the port used to construct it. "] fn chan(p: port) -> chan { - chan_t(rustrt::get_port_id(***p)) + chan_t(rustrt::get_port_id((**p).po)) } #[doc = " @@ -170,10 +177,10 @@ fn send(ch: chan, -data: T) { Receive from a port. If no data is available on the port then the task will block until data becomes available. "] -fn recv(p: port) -> T { recv_(***p) } +fn recv(p: port) -> T { recv_((**p).po) } #[doc = "Returns true if there are messages available"] -fn peek(p: port) -> bool { peek_(***p) } +fn peek(p: port) -> bool { peek_((**p).po) } #[doc(hidden)] fn recv_chan(ch: comm::chan) -> T { @@ -196,7 +203,7 @@ fn recv_(p: *rust_port) -> T { // Data isn't available yet, so res has not been initialized. task::yield(); } else { - // In the absense of compiler-generated preemption points + // In the absence of compiler-generated preemption points // this is a good place to yield task::yield(); } @@ -210,7 +217,7 @@ fn peek_(p: *rust_port) -> bool unsafe { #[doc = "Receive on one of two ports"] fn select2(p_a: port, p_b: port) -> either unsafe { - let ports = [***p_a, ***p_b]; + let ports = [(**p_a).po, (**p_b).po]; let n_ports = 2 as libc::size_t; let yield = 0u, yieldp = ptr::addr_of(yield); @@ -233,9 +240,9 @@ fn select2(p_a: port, p_b: port) // Now we know the port we're supposed to receive from assert resport != ptr::null(); - if resport == ***p_a { + if resport == (**p_a).po { either::left(recv(p_a)) - } else if resport == ***p_b { + } else if resport == (**p_b).po { either::right(recv(p_b)) } else { fail "unexpected result from rust_port_select"; @@ -482,4 +489,4 @@ fn test_port_detach_fail() { } } } -} \ No newline at end of file +} diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 913832a7f07..8f4b301adaf 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -39,7 +39,7 @@ export float, f32, f64; export box, char, str, ptr, vec, bool; export either, option, result, iter; export libc, os, io, run, rand, sys, unsafe, logging; -export arc, comm, task, future; +export arc, newcomm, comm, task, future; export extfmt; export tuple; export to_str; @@ -50,9 +50,9 @@ export num; // NDM seems to be necessary for resolve to work export option_iter; -// FIXME: This creates some APIs that I do not want to commit to. It is -// currently exported for the uv code in std, but when that code moves into -// core this should become unexported +// FIXME (#2648): This creates some APIs that I do not want to commit +// to. It is currently exported for the uv code in std, but when that +// code moves into core this should become unexported export priv; @@ -176,6 +176,7 @@ mod dvec_iter { // Concurrency mod arc; +mod newcomm; mod comm; mod task; mod future; diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 3ea8de957a0..85d61d3f606 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -113,6 +113,7 @@ impl extensions for dvec { and return a new vector to replace it with. "] + #[inline(always)] fn swap(f: fn(-[mut A]) -> [mut A]) { self.borrow { |v| self.return(f(v)) } } @@ -131,15 +132,6 @@ impl extensions for dvec { self.check_not_borrowed(); self.data <- w; } -} - -impl extensions for dvec { - #[doc = "Append a single item to the end of the list"] - fn push(t: A) { - self.swap { |v| - let mut v <- v; v += [t]; v // more efficient than v + [t] - } - } #[doc = "Remove and return the last element"] fn pop() -> A { @@ -151,6 +143,38 @@ impl extensions for dvec { } } + #[doc = "Insert a single item at the front of the list"] + fn unshift(-t: A) { + unsafe { + let mut data = unsafe::reinterpret_cast(null::<()>()); + data <-> self.data; + let data_ptr: *() = unsafe::reinterpret_cast(data); + if data_ptr.is_null() { fail "Recursive use of dvec"; } + log(error, "a"); + self.data <- [mut t] + data; + log(error, "b"); + } + } + + #[doc = "Append a single item to the end of the list"] + fn push(+t: A) { + self.check_not_borrowed(); + vec::push(self.data, t); + } + + + #[doc = "Remove and return the first element"] + fn shift() -> A { + self.borrow { |v| + let mut v = vec::from_mut(v); + let result = vec::shift(v); + self.return(vec::to_mut(v)); + result + } + } +} + +impl extensions for dvec { #[doc = " Append all elements of a vector to the end of the list @@ -170,7 +194,7 @@ impl extensions for dvec { vec::reserve(v, new_len); let mut i = from_idx; while i < to_idx { - v += [ts[i]]; + vec::push(v, ts[i]); i += 1u; } v @@ -213,16 +237,6 @@ impl extensions for dvec { } } - #[doc = "Remove and return the first element"] - fn shift() -> A { - self.borrow { |v| - let mut v = vec::from_mut(v); - let result = vec::shift(v); - self.return(vec::to_mut(v)); - result - } - } - #[doc = "Copy out an individual element"] #[inline(always)] fn [](idx: uint) -> A { diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index 1ae69046715..144ea571d7c 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -274,8 +274,8 @@ mod rt { enum count { count_is(int), count_implied, } enum ty { ty_default, ty_bits, ty_hex_upper, ty_hex_lower, ty_octal, } - // FIXME: May not want to use a vector here for flags; - // instead just use a bool per flag (see Issue #1993) + // FIXME (#1993): May not want to use a vector here for flags; instead + // just use a bool per flag. type conv = {flags: [flag], width: count, precision: count, ty: ty}; fn conv_int(cv: conv, i: int) -> str { diff --git a/src/libcore/f32.rs b/src/libcore/f32.rs index e1d30081966..821fa68f55c 100644 --- a/src/libcore/f32.rs +++ b/src/libcore/f32.rs @@ -6,8 +6,6 @@ import cmath::c_float::*; import cmath::c_float_targ_consts::*; import num::num; -// FIXME find out why these have to be exported explicitly - export add, sub, mul, div, rem, lt, le, gt, eq, eq, ne; export is_positive, is_negative, is_nonpositive, is_nonnegative; export is_zero, is_infinite, is_finite; @@ -55,9 +53,8 @@ pure fn ge(x: f32, y: f32) -> bool { ret x >= y; } pure fn gt(x: f32, y: f32) -> bool { ret x > y; } -// FIXME replace the predicates below with llvm intrinsics or calls -// to the libmath macros in the rust runtime for performance -// See Issue #1999 +// FIXME (#1999): replace the predicates below with llvm intrinsics or +// calls to the libmath macros in the rust runtime for performance. #[doc = " Returns true if `x` is a positive number, including +0.0f320 and +Infinity @@ -106,14 +103,13 @@ pure fn is_finite(x: f32) -> bool { ret !(is_NaN(x) || is_infinite(x)); } -// FIXME add is_normal, is_subnormal, and fpclassify -// also see Issue #1999 +// FIXME (#1999): add is_normal, is_subnormal, and fpclassify. /* Module: consts */ mod consts { - // FIXME replace with mathematical constants from cmath - // (requires Issue #1433 to fix) + // FIXME (requires Issue #1433 to fix): replace with mathematical + // constants from cmath. #[doc = "Archimedes' constant"] const pi: f32 = 3.14159265358979323846264338327950288_f32; @@ -167,9 +163,8 @@ pure fn logarithm(n: f32, b: f32) -> f32 { #[cfg(target_os="freebsd")] pure fn logarithm(n: f32, b: f32) -> f32 { - // FIXME check if it is good to use log2 instead of ln here; + // FIXME (#2000): check if it is good to use log2 instead of ln here; // in theory should be faster since the radix is 2 - // See Issue #2000 ret ln(n) / ln(b); } diff --git a/src/libcore/f64.rs b/src/libcore/f64.rs index af83a0829e1..066b1b818c7 100644 --- a/src/libcore/f64.rs +++ b/src/libcore/f64.rs @@ -29,8 +29,7 @@ export num; // PORT check per architecture -// FIXME obtain these in a different way -// (perhaps related to Issue #1433) +// FIXME (#1433): obtain these in a different way const radix: uint = 2u; @@ -127,14 +126,13 @@ pure fn is_finite(x: f64) -> bool { ret !(is_NaN(x) || is_infinite(x)); } -// FIXME add is_normal, is_subnormal, and fpclassify -// also see Issue #1999 +// FIXME (#1999): add is_normal, is_subnormal, and fpclassify /* Module: consts */ mod consts { - // FIXME replace with mathematical constants from cmath - // (requires Issue #1433 to fix) + // FIXME (requires Issue #1433 to fix): replace with mathematical + // constants from cmath. #[doc = "Archimedes' constant"] const pi: f64 = 3.14159265358979323846264338327950288_f64; @@ -188,9 +186,8 @@ pure fn logarithm(n: f64, b: f64) -> f64 { #[cfg(target_os="freebsd")] pure fn logarithm(n: f64, b: f64) -> f64 { - // FIXME check if it is good to use log2 instead of ln here; - // in theory should be faster since the radix is 2 - // See Issue #2000 + // FIXME (#2000): check if it is good to use log2 instead of ln here; in + // theory should be faster since the radix is 2 ret ln(n) / ln(b); } diff --git a/src/libcore/float.rs b/src/libcore/float.rs index f50719408d0..9c995100273 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -38,8 +38,8 @@ const neg_infinity: float = -1.0/0.0; /* Module: consts */ mod consts { - // FIXME replace with mathematical constants from cmath - // (requires Issue #1433 to fix) + // FIXME (requires Issue #1433 to fix): replace with mathematical + // constants from cmath. #[doc = "Archimedes' constant"] const pi: float = 3.14159265358979323846264338327950288; diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 077a178546e..635b3f9ebf4 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -22,14 +22,14 @@ native mod rustrt { // Reading -// FIXME This is all buffered. We might need an unbuffered variant as well -// #2004 +// FIXME (#2004): This is all buffered. We might need an unbuffered variant +// as well enum seek_style { seek_set, seek_end, seek_cur, } // The raw underlying reader iface. All readers must implement this. iface reader { - // FIXME: Seekable really should be orthogonal. // #2004 + // FIXME (#2004): Seekable really should be orthogonal. fn read_bytes(uint) -> [u8]; fn read_byte() -> int; fn unread_byte(int); @@ -82,8 +82,8 @@ impl reader_util for reader { while nbread > 0u { let data = self.read_bytes(nbread); if vec::len(data) == 0u { - // eof - FIXME should we do something if - // we're split in a unicode char? // #2004 + // eof - FIXME (#2004): should we do something if + // we're split in a unicode char? break; } buf += data; @@ -234,9 +234,9 @@ fn FILE_reader(f: *libc::FILE, cleanup: bool) -> reader { } } -// FIXME: this should either be an iface-less impl, a set of top-level -// functions that take a reader, or a set of default methods on reader -// (which can then be called reader) // #2004 +// FIXME (#2004): this should either be an iface-less impl, a set of +// top-level functions that take a reader, or a set of default methods on +// reader (which can then be called reader) fn stdin() -> reader { rustrt::rust_get_stdin() as reader } @@ -312,9 +312,8 @@ fn with_str_reader(s: str, f: fn(reader) -> T) -> T { // Writing enum fileflag { append, create, truncate, no_flag, } -// FIXME: Seekable really should be orthogonal. -// FIXME: eventually u64 -// #2004 +// FIXME (#2004): Seekable really should be orthogonal. +// FIXME (#2004): eventually u64 iface writer { fn write([const u8]/&); fn seek(int, seek_style); @@ -586,9 +585,9 @@ fn buffered_file_writer(path: str) -> result { else { result::ok(FILE_writer(f, true)) } } -// FIXME it would be great if this could be a const -// FIXME why are these different from the way stdin() is implemented? -// #2004 +// FIXME (#2004) it would be great if this could be a const +// FIXME (#2004) why are these different from the way stdin() is +// implemented? fn stdout() -> writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } fn stderr() -> writer { fd_writer(libc::STDERR_FILENO as c_int, false) } @@ -670,8 +669,8 @@ fn read_whole_file_str(file: str) -> result { }) } -// FIXME implement this in a low-level way. Going through the abstractions is -// pointless. // #2004 +// FIXME (#2004): implement this in a low-level way. Going through the +// abstractions is pointless. fn read_whole_file(file: str) -> result<[u8], str> { result::chain(file_reader(file), { |rdr| result::ok(rdr.read_whole_stream()) @@ -714,8 +713,8 @@ mod fsync { }; // fsync file after executing blk - // FIXME find better way to create resources within lifetime of outer res - // #2004 + // FIXME (#2004) find better way to create resources within lifetime of + // outer res fn FILE_res_sync(&&file: FILE_res, opt_level: option, blk: fn(&&res<*libc::FILE>)) { blk(res({ diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index cf903c3bebe..070e909c626 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -97,8 +97,8 @@ fn min>(self: IA) -> A { alt foldl::,IA>(self, none) {|a, b| alt a { some(a_) if a_ < b { - // FIXME: Not sure if this is successfully optimized to a move - // #2005 + // FIXME (#2005): Not sure if this is successfully optimized to + // a move a } _ { some(b) } @@ -113,8 +113,8 @@ fn max>(self: IA) -> A { alt foldl::,IA>(self, none) {|a, b| alt a { some(a_) if a_ > b { - // FIXME: Not sure if this is successfully optimized to a move - // #2005 + // FIXME (#2005): Not sure if this is successfully optimized to + // a move. a } _ { some(b) } diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index b6861b42eb7..c2679c6956e 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -37,8 +37,7 @@ dissolved. // Initial glob-exports mean that all the contents of all the modules // wind up exported, if you're interested in writing platform-specific code. -// FIXME: change these to glob-exports when sufficiently supported. -// Issue #2006 +// FIXME (#2006): change these to glob-exports when sufficiently supported. import types::common::c95::*; import types::common::c99::*; @@ -79,10 +78,9 @@ import funcs::posix08::unistd::*; import funcs::bsd44::*; import funcs::extra::*; -// FIXME: remove these 3 exports (and their uses next door in os::) when -// export globs work. They provide access (for now) for os:: to dig around in -// the rest of the platform-specific definitions. -// Issue #2006 +// FIXME (#2006): remove these 3 exports (and their uses next door in os::) +// when export globs work. They provide access (for now) for os:: to dig +// around in the rest of the platform-specific definitions. export types, funcs, consts; diff --git a/src/libcore/newcomm.rs b/src/libcore/newcomm.rs new file mode 100644 index 00000000000..24c4c1cbd9c --- /dev/null +++ b/src/libcore/newcomm.rs @@ -0,0 +1,82 @@ +#[doc="A new implementation of communication. + +This should be implementing almost entirely in Rust, and hopefully +avoid needing a single global lock."] + +import arc::methods; +import dvec::dvec; +import dvec::{extensions}; + +export port; +export chan; +export send, recv; +export methods; + +type raw_port = arc::exclusive>; + +enum port { + port_(raw_port) +} +enum chan { + chan_(raw_port) +} + +fn port() -> port { + port_(arc::exclusive(dvec())) +} + +fn chan(p: port) -> chan { + chan_((*p).clone()) +} + +fn send(c: chan, -x: T) { + let mut x <- some(x); + (*c).with {|cond, data| + let mut xx = none; + xx <-> x; + (*data).push(option::unwrap(xx)); + cond.signal(); + } +} + +fn recv(p: port) -> T { + (*p).with {|cond, data| + if (*data).len() == 0u { + cond.wait(); + } + assert (*data).len() > 0u; + (*data).shift() + } +} + +impl methods for chan { + fn send(-x: T) { + send(self, x) + } + + fn clone() -> chan { + chan_((*self).clone()) + } +} + +impl methods for port { + fn recv() -> T { + recv(self) + } + + fn chan() -> chan { + chan(self) + } +} + +#[cfg(test)] +mod test { + #[test] + fn newport_simple() { + let p = port(); + let c = chan(p); + + c.send(42); + assert p.recv() == 42; + } +} diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 34c38321f47..9ee7a80fcda 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -166,8 +166,8 @@ mod global_env { task::set_opts(builder, { sched: some({ mode: task::single_threaded, - // FIXME: This would be a good place to use - // a very small native stack (#2621) + // FIXME (#2621): This would be a good place to use a + // very small native stack native_stack_size: none }) with task::get_opts(builder) @@ -499,8 +499,8 @@ fn path_exists(p: path) -> bool { } } -// FIXME: under Windows, we should prepend the current drive letter to paths -// that start with a slash. #2622 +// FIXME (#2622): under Windows, we should prepend the current drive letter +// to paths that start with a slash. #[doc = " Convert a relative path to an absolute path @@ -696,8 +696,8 @@ fn remove_file(p: path) -> bool { #[cfg(windows)] fn unlink(p: path) -> bool { - // FIXME: remove imports when export globs work properly. - // (similar to Issue #2006) + // FIXME (similar to Issue #2006): remove imports when export globs + // work properly. import libc::funcs::extra::kernel32::*; import libc::types::os::arch::extra::*; import win32::*; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 2ce5550d951..2a89abc040f 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -10,6 +10,7 @@ export is_null; export is_not_null; export memcpy; export memmove; +export memset; export buf_len; export position; export extensions; @@ -23,6 +24,8 @@ native mod libc_ { fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void; #[rust_stack] fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void; + #[rust_stack] + fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void; } #[abi = "rust-intrinsic"] @@ -108,6 +111,12 @@ unsafe fn memmove(dst: *T, src: *T, count: uint) { libc_::memmove(dst as *c_void, src as *c_void, n as size_t); } +#[inline(always)] +unsafe fn memset(dst: *mut T, c: int, count: uint) { + let n = count * sys::size_of::(); + libc_::memset(dst as *c_void, c as libc::c_int, n as size_t); +} + #[doc = "Extension methods for pointers"] impl extensions for *T { #[doc = "Returns true if the pointer is equal to the null pointer."] diff --git a/src/libcore/run.rs b/src/libcore/run.rs index d8905730dc2..401454c40df 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -286,8 +286,8 @@ fn program_output(prog: str, args: [str]) -> // Spawn two entire schedulers to read both stdout and sterr // in parallel so we don't deadlock while blocking on one - // or the other. FIXME: Surely there's a much more clever way - // to do this. (#2625) + // or the other. FIXME (#2625): Surely there's a much more + // clever way to do this. let p = comm::port(); let ch = comm::chan(p); task::spawn_sched(task::single_threaded) {|| diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 321fa605f48..0041dde319d 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -23,10 +23,10 @@ fn walk_stack(visit: fn(frame) -> bool) { reinterpret_cast(frame_pointer) }; loop { - let frame = frame(frame_address); + let fr = frame(frame_address); - #debug("frame: %x", unsafe { reinterpret_cast(frame.fp) }); - visit(frame); + #debug("frame: %x", unsafe { reinterpret_cast(fr.fp) }); + visit(fr); unsafe { let next_fp: **word = reinterpret_cast(frame_address); @@ -44,7 +44,7 @@ fn walk_stack(visit: fn(frame) -> bool) { #[test] fn test_simple() { - for walk_stack { |frame| + for walk_stack { |_frame| } } @@ -53,7 +53,7 @@ fn test_simple_deep() { fn run(i: int) { if i == 0 { ret } - for walk_stack { |frame| + for walk_stack { |_frame| unsafe { breakpoint(); } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 8f68ff8d4da..dbdd798033c 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -566,7 +566,7 @@ pure fn to_upper(s: str/&) -> str { } #[doc = " -Replace all occurances of one string with another +Replace all occurrences of one string with another # Arguments @@ -593,8 +593,8 @@ Section: Comparing strings #[doc = "Bytewise string equality"] pure fn eq(&&a: str, &&b: str) -> bool { - // FIXME: This should just be "a == b" but that calls into the shape code - // :( (#2627) + // FIXME (#2627): This should just be "a == b" but that calls into the + // shape code. let a_len = a.len(); let b_len = b.len(); if a_len != b_len { ret false; } @@ -1743,8 +1743,9 @@ mod unsafe { Does not verify that the vector contains valid UTF-8. "] unsafe fn from_bytes(v: [const u8]) -> str unsafe { - let vcopy = v + [0u8]; - ret ::unsafe::transmute(vcopy); + let mut vcopy : [u8] = ::unsafe::transmute(copy v); + vec::push(vcopy, 0u8); + ::unsafe::transmute(vcopy) } #[doc = " diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 1e4e5b17bb9..77207d8aebf 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -51,6 +51,7 @@ pure fn get_type_desc() -> *type_desc { } #[doc = "Returns the size of a type"] +#[inline(always)] pure fn size_of() -> uint unsafe { unchecked { rusti::size_of::() } } diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 5f31b5090f0..ab9b4f7d3d7 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -64,8 +64,8 @@ Indicates the manner in which a task exited. A task that completes without failing and whose supervised children complete without failing is considered to exit successfully. -FIXME: This description does not indicate the current behavior for linked -failure. (See #1868) +FIXME (See #1868): This description does not indicate the current behavior +for linked failure. "] enum task_result { success, @@ -275,7 +275,7 @@ fn future_result(builder: builder) -> future::future { task. "]; - // FIXME (1087, 1857): Once linked failure and notification are + // FIXME (#1087, #1857): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and // sending out messages. @@ -506,10 +506,10 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe { let mut f = if opts.supervise { f } else { - // FIXME: The runtime supervision API is weird here because it - // was designed to let the child unsupervise itself, when what - // we actually want is for parents to unsupervise new - // children. (#1868, #1789) + // FIXME (#1868, #1789): The runtime supervision API is weird here + // because it was designed to let the child unsupervise itself, + // when what we actually want is for parents to unsupervise new + // children. fn~() { rustrt::unsupervise(); f(); @@ -529,7 +529,7 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe { }; option::iter(opts.notify_chan) {|c| - // FIXME (1087): Would like to do notification in Rust + // FIXME (#1087): Would like to do notification in Rust rustrt::rust_task_config_notify(new_task, c); } diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs index f58a85c3618..be491433cd0 100644 --- a/src/libcore/uint-template.rs +++ b/src/libcore/uint-template.rs @@ -173,10 +173,9 @@ fn to_str_bytes(neg: bool, num: T, radix: uint, 0u8,0u8,0u8,0u8,0u8 ]/65; - // FIXME: post-snapshot, you can do this without - // the raw pointers and unsafe bits, and the - // codegen will prove it's all in-bounds, no - // extra cost. + // FIXME (#2649): post-snapshot, you can do this without the raw + // pointers and unsafe bits, and the codegen will prove it's all + // in-bounds, no extra cost. vec::unpack_slice(buf) {|p, len| let mp = p as *mut u8; diff --git a/src/libcore/uint-template/uint.rs b/src/libcore/uint-template/uint.rs index e1bb89c27c4..843215bd4b9 100644 --- a/src/libcore/uint-template/uint.rs +++ b/src/libcore/uint-template/uint.rs @@ -81,6 +81,7 @@ fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { } #[doc = "Returns the smallest power of 2 greater than or equal to `n`"] +#[inline(always)] fn next_power_of_two(n: uint) -> uint { let halfbits: uint = sys::size_of::() * 4u; let mut tmp: uint = n - 1u; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 1eab5b12ea0..494470e32e4 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -4,6 +4,7 @@ import option::{some, none}; import ptr::addr_of; import libc::size_t; +export append; export init_op; export is_empty; export is_not_empty; @@ -91,6 +92,11 @@ native mod rustrt { ++count: libc::size_t) -> *unsafe::vec_repr; } +#[abi = "rust-intrinsic"] +native mod rusti { + fn move_val_init(&dst: T, -src: T); +} + #[doc = "A function used to initialize the elements of a vector"] type init_op = fn(uint) -> T; @@ -187,7 +193,9 @@ pure fn from_elem(n_elts: uint, t: T) -> [T] { let mut v = []; unchecked{reserve(v, n_elts)} let mut i: uint = 0u; - while i < n_elts { v += [t]; i += 1u; } + unsafe { // because push is impure + while i < n_elts { push(v, t); i += 1u; } + } ret v; } @@ -363,20 +371,30 @@ fn rsplitn(v: [T]/&, n: uint, f: fn(T) -> bool) -> [[T]] { // Mutators #[doc = "Removes the first element from a vector and return it"] -fn shift(&v: [T]) -> T { +fn shift(&v: [T]) -> T { let ln = len::(v); assert (ln > 0u); - let e = v[0]; - v = slice::(v, 1u, ln); - ret e; -} -#[doc = "Prepend an element to a vector"] -fn unshift(&v: [const T], +t: T) { - // n.b.---for most callers, using unshift() ought not to type check, but - // it does. It's because the type system is unaware of the mutability of - // `v` and so allows the vector to be covariant. - v = [const t] + v; + let mut vv = []; + v <-> vv; + + unsafe { + let mut rr; + { + let vv = unsafe::to_ptr(vv); + let mut r <- *vv; + + for uint::range(1u, ln) {|i| + // FIXME (#2703): this isn't legal, per se... + let r <- *ptr::offset(vv, i); + push(v, r); + } + rr <- r; + } + unsafe::set_len(vv, 0u); + + rr + } } #[doc = "Remove the last element from a vector and return it"] @@ -390,12 +408,85 @@ fn pop(&v: [const T]) -> T unsafe { } #[doc = "Append an element to a vector"] +#[inline(always)] fn push(&v: [const T], +initval: T) { - v += [initval]; + unsafe { + let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); + let fill = (**repr).fill; + if (**repr).alloc > fill { + let sz = sys::size_of::(); + (**repr).fill += sz; + let p = ptr::addr_of((**repr).data); + let p = ptr::offset(p, fill) as *mut T; + rusti::move_val_init(*p, initval); + } + else { + push_slow(v, initval); + } + } } +fn push_slow(&v: [const T], +initval: T) { + unsafe { + let ln = v.len(); + reserve_at_least(v, ln + 1u); + let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); + let fill = (**repr).fill; + let sz = sys::size_of::(); + (**repr).fill += sz; + let p = ptr::addr_of((**repr).data); + let p = ptr::offset(p, fill) as *mut T; + rusti::move_val_init(*p, initval); + } +} + +#[inline(always)] +fn push_all(&v: [const T], rhs: [const T]/&) { + for uint::range(0u, rhs.len()) {|i| + push(v, rhs[i]); + } +} // Appending +#[inline(always)] +pure fn append(lhs: [T]/&, rhs: [const T]/&) -> [T] { + let mut v = []; + let mut i = 0u; + while i < lhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, lhs[i]); + } + i += 1u; + } + i = 0u; + while i < rhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, rhs[i]); + } + i += 1u; + } + ret v; +} + +#[inline(always)] +pure fn append_mut(lhs: [mut T]/&, rhs: [const T]/&) -> [mut T] { + let mut v = [mut]; + let mut i = 0u; + while i < lhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, lhs[i]); + } + i += 1u; + } + i = 0u; + while i < rhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, rhs[i]); + } + i += 1u; + } + ret v; +} #[doc = " Expands a vector in place, initializing the new elements to a given value @@ -409,7 +500,8 @@ Expands a vector in place, initializing the new elements to a given value fn grow(&v: [const T], n: uint, initval: T) { reserve_at_least(v, len(v) + n); let mut i: uint = 0u; - while i < n { v += [initval]; i += 1u; } + + while i < n { push(v, initval); i += 1u; } } #[doc = " @@ -428,7 +520,7 @@ Function `init_op` is called `n` times with the values [0..`n`) fn grow_fn(&v: [const T], n: uint, op: init_op) { reserve_at_least(v, len(v) + n); let mut i: uint = 0u; - while i < n { v += [op(i)]; i += 1u; } + while i < n { push(v, op(i)); i += 1u; } } #[doc = " @@ -439,6 +531,7 @@ Sets the element at position `index` to `val`. If `index` is past the end of the vector, expands the vector by replicating `initval` to fill the intervening space. "] +#[inline(always)] fn grow_set(&v: [mut T], index: uint, initval: T, val: T) { if index >= len(v) { grow(v, index - len(v) + 1u, initval); } v[index] = val; @@ -453,7 +546,7 @@ Apply a function to each element of a vector and return the results pure fn map(v: [T]/&, f: fn(T) -> U) -> [U] { let mut result = []; unchecked{reserve(result, len(v));} - for each(v) {|elem| result += [f(elem)]; } + for each(v) {|elem| unsafe { push(result, f(elem)); } } ret result; } @@ -486,7 +579,10 @@ pure fn map2(v0: [T]/&, v1: [U]/&, if v0_len != len(v1) { fail; } let mut u: [V] = []; let mut i = 0u; - while i < v0_len { u += [f(copy v0[i], copy v1[i])]; i += 1u; } + while i < v0_len { + unsafe { push(u, f(copy v0[i], copy v1[i])) }; + i += 1u; + } ret u; } @@ -502,7 +598,7 @@ pure fn filter_map(v: [T]/&, f: fn(T) -> option) for each(v) {|elem| alt f(elem) { none {/* no-op */ } - some(result_elem) { result += [result_elem]; } + some(result_elem) { unsafe { push(result, result_elem); } } } } ret result; @@ -518,7 +614,7 @@ only those elements for which `f` returned true. pure fn filter(v: [T]/&, f: fn(T) -> bool) -> [T] { let mut result = []; for each(v) {|elem| - if f(elem) { result += [elem]; } + if f(elem) { unsafe { push(result, elem); } } } ret result; } @@ -530,7 +626,7 @@ Flattens a vector of vectors of T into a single vector of T. "] pure fn concat(v: [[T]]/&) -> [T] { let mut r = []; - for each(v) {|inner| r += inner; } + for each(v) {|inner| unsafe { push_all(r, inner); } } ret r; } @@ -541,7 +637,7 @@ pure fn connect(v: [[T]]/&, sep: T) -> [T] { let mut r: [T] = []; let mut first = true; for each(v) {|inner| - if first { first = false; } else { r += [sep]; } + if first { first = false; } else { unsafe { push(r, sep); } } r += inner; } ret r; @@ -1025,6 +1121,20 @@ pure fn unpack_mut_slice(s: [mut T]/&, f(buf, len / sys::size_of::()) } +impl extensions for [T] { + #[inline(always)] + pure fn +(rhs: [T]/&) -> [T] { + append(self, rhs) + } +} + +impl extensions for [mut T] { + #[inline(always)] + pure fn +(rhs: [mut T]/&) -> [mut T] { + append_mut(self, rhs) + } +} + #[doc = "Extension methods for vectors"] impl extensions/& for [const T]/& { #[doc = "Returns true if a vector contains no elements"] @@ -2088,13 +2198,6 @@ mod tests { assert addr == addr_imm; } - #[test] - fn test_unshift() { - let mut x = [1, 2, 3]; - unshift(x, 0); - assert x == [0, 1, 2, 3]; - } - #[test] fn test_capacity() { let mut v = [0u64]; diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 1be4d12d23e..254ed4d4ede 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -16,11 +16,10 @@ export to_vec; export to_str; export eq_vec; -// FIXME: With recursive object types, we could implement binary methods like -// union, intersection, and difference. At that point, we could write -// an optimizing version of this module that produces a different obj -// for the case where nbits <= 32. -// (Issue #2341) +// FIXME (#2341): With recursive object types, we could implement binary +// methods like union, intersection, and difference. At that point, we could +// write an optimizing version of this module that produces a different obj +// for the case where nbits <= 32. #[doc = "The bitvector type"] type bitv = @{storage: [mut uint], nbits: uint}; diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 1e9b2224a63..f57d2a21af6 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -14,8 +14,8 @@ iface t { fn get(int) -> T; } -// FIXME eventually, a proper datatype plus an exported impl would be -// preferrable (#2343) +// FIXME (#2343) eventually, a proper datatype plus an exported impl would +// be preferrable. fn create() -> t { type cell = option; @@ -33,8 +33,8 @@ fn create() -> t { let nalloc = uint::next_power_of_two(nelts + 1u); while i < nalloc { if i < nelts { - rv += [mut elts[(lo + i) % nelts]]; - } else { rv += [mut none]; } + vec::push(rv, elts[(lo + i) % nelts]); + } else { vec::push(rv, none); } i += 1u; } diff --git a/src/libstd/map.rs b/src/libstd/map.rs index bfa1fb4a7b6..c988b167fd0 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -67,8 +67,8 @@ iface map { fn each_value(fn(V) -> bool); } -// FIXME: package this up and export it as a datatype usable for -// external code that doesn't want to pay the cost of a box. (#2344) +// FIXME (#2344): package this up and export it as a datatype usable for +// external code that doesn't want to pay the cost of a box. mod chained { export t, mk, hashmap; diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 024a4367eb8..64cded848d1 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -36,7 +36,7 @@ fn format_addr(ip: ip_addr) -> str { #fmt["%u.%u.%u.%u", a as uint, b as uint, c as uint, d as uint] } ipv6(_, _, _, _, _, _, _, _) { - fail "FIXME impl parsing of ipv6 addr"; + fail "FIXME (#2651) impl parsing of ipv6 addr"; } } } diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 0b06dd67f76..a2d36ac354b 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -2,15 +2,12 @@ High-level interface to libuv's TCP functionality "]; -// FIXME: Fewer import *'s import ip = net_ip; import uv::iotask; import uv::iotask::iotask; -import comm::*; -import result::*; -import str::*; -import future::*; -import libc::size_t; +import comm::methods; +import future::future; +import result::{result,err,ok,extensions}; // data export tcp_socket, tcp_conn_port, tcp_err_data; @@ -364,8 +361,8 @@ fn new_listener(host_ip: ip::ip_addr, port: uint, backlog: uint, let new_conn_po = comm::port::>(); let new_conn_ch = comm::chan(new_conn_po); - // FIXME: This shared box should not be captured in the i/o task - // Make it a unique pointer. + // FIXME (#2656): This shared box should not be captured in the i/o + // task Make it a unique pointer. let server_data: @tcp_conn_port_data = @{ server_stream: uv::ll::tcp_t(), stream_closed_po: stream_closed_po, @@ -946,10 +943,10 @@ fn write_common_impl(socket_data_ptr: *tcp_socket_data, } } }; - // FIXME: Instead of passing unsafe pointers to local data, and waiting - // here for the write to complete, we should transfer ownership of - // everything to the I/O task and let it deal with the aftermath, - // so we don't have to sit here blocking. + // FIXME (#2656): Instead of passing unsafe pointers to local data, + // and waiting here for the write to complete, we should transfer + // ownership of everything to the I/O task and let it deal with the + // aftermath, so we don't have to sit here blocking. alt comm::recv(result_po) { tcp_write_success { result::ok(()) } tcp_write_error(err_data) { result::err(err_data.to_tcp_err()) } @@ -1191,20 +1188,16 @@ crust fn tcp_write_complete_cb(write_req: *uv::ll::uv_write_t, status: libc::c_int) unsafe { let write_data_ptr = uv::ll::get_data_for_req(write_req) as *write_req_data; - // FIXME: if instead of alt - alt status { - 0i32 { + if status == 0i32 { log(debug, "successful write complete"); comm::send((*write_data_ptr).result_ch, tcp_write_success); - } - _ { + } else { let stream_handle_ptr = uv::ll::get_stream_handle_from_write_req( write_req); let loop_ptr = uv::ll::get_loop_for_uv_handle(stream_handle_ptr); let err_data = uv::ll::get_last_err_data(loop_ptr); log(debug, "failure to write"); comm::send((*write_data_ptr).result_ch, tcp_write_error(err_data)); - } } } @@ -1273,20 +1266,20 @@ type tcp_socket_data = { // convert rust ip_addr to libuv's native representation fn ipv4_ip_addr_to_sockaddr_in(input_ip: ip::ip_addr, port: uint) -> uv::ll::sockaddr_in unsafe { - // FIXME ipv6 + // FIXME (#2656): ipv6 alt input_ip { ip::ipv4(_,_,_,_) { uv::ll::ip4_addr(ip::format_addr(input_ip), port as int) } ip::ipv6(_,_,_,_,_,_,_,_) { - fail "FIXME ipv6 not yet supported"; + fail "FIXME (#2656) ipv6 not yet supported"; } } } #[cfg(test)] mod test { - // FIXME don't run on fbsd or linux 32 bit(#2064) + // FIXME don't run on fbsd or linux 32 bit (#2064) #[cfg(target_os="win32")] #[cfg(target_os="darwin")] #[cfg(target_os="linux")] diff --git a/src/libstd/par.rs b/src/libstd/par.rs index ffca5989857..e621fd78724 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -7,7 +7,7 @@ import future::future; export map, mapi, alli, any, mapi_factory; #[doc="The maximum number of tasks this module will spawn for a single -operationg."] +operation."] const max_tasks : uint = 32u; #[doc="The minimum number of elements each task will process."] diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 945b23cc47a..a8cd3b65ef8 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -864,7 +864,7 @@ mod node { loop { alt (leaf_iterator::next(it)) { option::none { break; } - option::some(x) { forest += [mut @leaf(x)]; } + option::some(x) { vec::push(forest, @leaf(x)); } } } //2. Rebuild tree from forest diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 1abf54b438d..89e9d0338fe 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -6,8 +6,8 @@ import core::option; import core::option::{some, none}; import dvec::{dvec, extensions}; -// FIXME: Should not be @; there's a bug somewhere in rustc that requires this -// to be. (#2347) +// FIXME (#2347): Should not be @; there's a bug somewhere in rustc that +// requires this to be. type smallintmap = @{v: dvec>}; #[doc = "Create a smallintmap"] @@ -19,6 +19,7 @@ fn mk() -> smallintmap { Add a value to the map. If the map already contains a value for the specified key then the original value is replaced. "] +#[inline(always)] fn insert(self: smallintmap, key: uint, val: T) { self.v.grow_set_elt(key, none, some(val)); } @@ -62,6 +63,7 @@ impl of map::map for smallintmap { } sz } + #[inline(always)] fn insert(+key: uint, +value: V) -> bool { let exists = contains_key(self, key); insert(self, key, value); diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 2c7902c63e9..d06749b5757 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -319,15 +319,14 @@ fn strptime(s: str, format: str) -> result { .chain { |pos| parse_type(s, pos, 'd', tm) } } 'H' { - // FIXME: range check. (#2350 -- same issue for all FIXMEs in this - // file.) + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, false) { some(item) { let (v, pos) = item; tm.tm_hour = v; ok(pos) } none { err("Invalid hour") } } } 'I' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, false) { some(item) { let (v, pos) = item; @@ -338,7 +337,7 @@ fn strptime(s: str, format: str) -> result { } } 'j' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 3u, false) { some(item) { let (v, pos) = item; @@ -349,14 +348,14 @@ fn strptime(s: str, format: str) -> result { } } 'k' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, true) { some(item) { let (v, pos) = item; tm.tm_hour = v; ok(pos) } none { err("Invalid hour") } } } 'l' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, true) { some(item) { let (v, pos) = item; @@ -367,14 +366,14 @@ fn strptime(s: str, format: str) -> result { } } 'M' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, false) { some(item) { let (v, pos) = item; tm.tm_min = v; ok(pos) } none { err("Invalid minute") } } } 'm' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, false) { some(item) { let (v, pos) = item; @@ -412,7 +411,7 @@ fn strptime(s: str, format: str) -> result { .chain { |pos| parse_type(s, pos, 'p', tm) } } 'S' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, false) { some(item) { let (v, pos) = item; @@ -432,7 +431,7 @@ fn strptime(s: str, format: str) -> result { } 't' { parse_char(s, pos, '\t') } 'u' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 1u, false) { some(item) { let (v, pos) = item; @@ -451,7 +450,7 @@ fn strptime(s: str, format: str) -> result { } //'W' {} 'w' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 1u, false) { some(item) { let (v, pos) = item; tm.tm_wday = v; ok(pos) } none { err("Invalid weekday") } @@ -460,7 +459,7 @@ fn strptime(s: str, format: str) -> result { //'X' {} //'x' {} 'Y' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 4u, false) { some(item) { let (v, pos) = item; @@ -471,7 +470,7 @@ fn strptime(s: str, format: str) -> result { } } 'y' { - // FIXME: range check. + // FIXME (#2350): range check. alt match_digits(s, pos, 2u, false) { some(item) { let (v, pos) = item; @@ -584,7 +583,7 @@ fn strptime(s: str, format: str) -> result { fn strftime(format: str, tm: tm) -> str { fn parse_type(ch: char, tm: tm) -> str { - //FIXME: Implement missing types. + //FIXME (#2350): Implement missing types. alt check ch { 'A' { alt check tm.tm_wday as int { @@ -915,7 +914,7 @@ mod tests { assert local.tm_isdst == 0_i32; assert local.tm_gmtoff == -28800_i32; - // FIXME: We should probably standardize on the timezone + // FIXME (#2350): We should probably standardize on the timezone // abbreviation. let zone = local.tm_zone; assert zone == "PST" || zone == "Pacific Standard Time"; @@ -1063,8 +1062,8 @@ mod tests { assert test("2009-02-13", "%F"); assert test("03", "%H"); assert test("13", "%H"); - assert test("03", "%I"); // FIXME: flesh out - assert test("11", "%I"); // FIXME: flesh out + assert test("03", "%I"); // FIXME (#2350): flesh out + assert test("11", "%I"); // FIXME (#2350): flesh out assert test("044", "%j"); assert test(" 3", "%k"); assert test("13", "%k"); @@ -1162,7 +1161,7 @@ mod tests { assert local.strftime("%Y") == "2009"; assert local.strftime("%y") == "09"; - // FIXME: We should probably standardize on the timezone + // FIXME (#2350): We should probably standardize on the timezone // abbreviation. let zone = local.strftime("%Z"); assert zone == "PST" || zone == "Pacific Standard Time"; @@ -1170,7 +1169,7 @@ mod tests { assert local.strftime("%z") == "-0800"; assert local.strftime("%%") == "%"; - // FIXME: We should probably standardize on the timezone + // FIXME (#2350): We should probably standardize on the timezone // abbreviation. let rfc822 = local.rfc822(); let prefix = "Fri, 13 Feb 2009 15:31:30 "; diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index e882eba5d6b..b7e1ee7d82c 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -505,7 +505,7 @@ native mod rustrt { tcp_handle_ptr: *uv_tcp_t, ++after_cb: *u8, ++addr: *sockaddr_in) -> libc::c_int; - // FIXME ref 2064 + // FIXME ref #2064 fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> libc::c_int; fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 98cf35efdc8..9d3dcb0f23e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -176,9 +176,7 @@ enum proto { #[auto_serialize] enum vstore { - /* FIXME: Change uint to @expr (actually only constant exprs, - as per #2112) - */ + // FIXME (#2112): Change uint to @expr (actually only constant exprs) vstore_fixed(option), // [1,2,3,4]/_ or 4 vstore_uniq, // [1,2,3,4]/~ vstore_box, // [1,2,3,4]/@ @@ -256,12 +254,11 @@ enum init_op { init_assign, init_move, } #[auto_serialize] type initializer = {op: init_op, expr: @expr}; +// FIXME (pending discussion of #1697, #2178...): local should really be +// a refinement on pat. #[auto_serialize] -type local_ = /* FIXME: should really be a refinement on pat - (pending discussion of #1697, #2178...) - */ - {is_mutbl: bool, ty: @ty, pat: @pat, - init: option, id: node_id}; +type local_ = {is_mutbl: bool, ty: @ty, pat: @pat, + init: option, id: node_id}; #[auto_serialize] type local = spanned; @@ -322,9 +319,8 @@ enum expr_ { expr_block(blk), /* - * FIXME: many of these @exprs should be constrained with + * FIXME (#34): many of these @exprs should be constrained with * is_lval once we have constrained types working. - * (See #34) */ expr_copy(@expr), expr_move(@expr, @expr), diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index e11e673494c..9355da5779e 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -13,8 +13,8 @@ type path = [path_elt]; fn path_to_str_with_sep(p: path, sep: str) -> str { let strs = vec::map(p) {|e| alt e { - path_mod(s) { /* FIXME: bad */ copy *s } - path_name(s) { /* FIXME: bad */ copy *s } + path_mod(s) { /* FIXME (#2543) */ copy *s } + path_name(s) { /* FIXME (#2543) */ copy *s } } }; str::connect(strs, sep) @@ -22,7 +22,7 @@ fn path_to_str_with_sep(p: path, sep: str) -> str { fn path_ident_to_str(p: path, i: ident) -> str { if vec::is_empty(p) { - /* FIXME: bad */ copy *i + /* FIXME (#2543) */ copy *i } else { #fmt["%s::%s", path_to_str(p), *i] } @@ -98,7 +98,7 @@ fn map_decoded_item(diag: span_handler, // even if we did I think it only needs an ordering between local // variables that are simultaneously in scope). let cx = {map: map, - mut path: /* FIXME: bad */ copy path, + mut path: /* FIXME (#2543) */ copy path, mut local_id: 0u, diag: diag}; let v = mk_ast_map_visitor(); @@ -124,27 +124,29 @@ fn map_decoded_item(diag: span_handler, fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: codemap::span, id: node_id, cx: ctx, v: vt) { for decl.inputs.each {|a| - cx.map.insert(a.id, node_arg(/* FIXME: bad */ copy a, cx.local_id)); + cx.map.insert(a.id, + node_arg(/* FIXME (#2543) */ + copy a, cx.local_id)); cx.local_id += 1u; } alt fk { visit::fk_ctor(nm, tps, self_id, parent_id) { let ct = @{node: {id: id, self_id: self_id, - dec: /* FIXME: bad */ copy decl, - body: /* FIXME: bad */ copy body}, + dec: /* FIXME (#2543) */ copy decl, + body: /* FIXME (#2543) */ copy body}, span: sp}; - cx.map.insert(id, node_ctor(/* FIXME: bad */ copy nm, - /* FIXME: bad */ copy tps, + cx.map.insert(id, node_ctor(/* FIXME (#2543) */ copy nm, + /* FIXME (#2543) */ copy tps, class_ctor(ct, parent_id), - @/* FIXME: bad */ copy cx.path)); + @/* FIXME (#2543) */ copy cx.path)); } visit::fk_dtor(tps, self_id, parent_id) { let dt = @{node: {id: id, self_id: self_id, - body: /* FIXME: bad */ copy body}, span: sp}; - cx.map.insert(id, node_dtor(/* FIXME: bad */ copy tps, dt, + body: /* FIXME (#2543) */ copy body}, span: sp}; + cx.map.insert(id, node_dtor(/* FIXME (#2543) */ copy tps, dt, parent_id, - @/* FIXME: bad */ copy cx.path)); + @/* FIXME (#2543) */ copy cx.path)); } _ {} @@ -153,7 +155,7 @@ fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, } fn map_block(b: blk, cx: ctx, v: vt) { - cx.map.insert(b.node.id, node_block(/* FIXME: bad */ copy b)); + cx.map.insert(b.node.id, node_block(/* FIXME (#2543) */ copy b)); visit::visit_block(b, cx, v); } @@ -187,7 +189,7 @@ fn map_method(impl_did: def_id, impl_path: @path, } fn map_item(i: @item, cx: ctx, v: vt) { - let item_path = @/* FIXME: bad */ copy cx.path; + let item_path = @/* FIXME (#2543) */ copy cx.path; cx.map.insert(i.id, node_item(i, item_path)); alt i.node { item_impl(_, _, _, _, ms) { @@ -198,9 +200,10 @@ fn map_item(i: @item, cx: ctx, v: vt) { } } item_res(decl, tps, _, dtor_id, ctor_id, _) { - cx.map.insert(ctor_id, node_ctor(/* FIXME: bad */ copy i.ident, - /* FIXME: bad */ copy tps, - res_ctor(/* FIXME: bad */ copy decl, + cx.map.insert(ctor_id, node_ctor(/* FIXME (#2543) */ copy i.ident, + /* FIXME (#2543) */ copy tps, + res_ctor(/* FIXME (#2543) */ + copy decl, ctor_id, i.span), item_path)); cx.map.insert(dtor_id, node_item(i, item_path)); @@ -208,7 +211,7 @@ fn map_item(i: @item, cx: ctx, v: vt) { item_enum(vs, _, _) { for vs.each {|v| cx.map.insert(v.node.id, node_variant( - /* FIXME: bad */ copy v, i, + /* FIXME (#2543) */ copy v, i, extend(cx, i.ident))); } } @@ -220,7 +223,8 @@ fn map_item(i: @item, cx: ctx, v: vt) { for nm.items.each {|nitem| cx.map.insert(nitem.id, node_native_item(nitem, abi, - @/* FIXME: bad */ copy cx.path)); + /* FIXME (#2543) */ + @copy cx.path)); } } item_class(tps, ifces, items, ctor, dtor, _) { @@ -251,7 +255,9 @@ fn map_view_item(vi: @view_item, cx: ctx, _v: vt) { view_item_export(vps) { for vps.each {|vp| let (id, name) = alt vp.node { - view_path_simple(nm, _, id) { (id, /* FIXME: bad */ copy nm) } + view_path_simple(nm, _, id) { + (id, /* FIXME (#2543) */ copy nm) + } view_path_glob(pth, id) | view_path_list(pth, _, id) { (id, path_to_ident(pth)) } @@ -294,19 +300,19 @@ fn node_id_to_str(map: map, id: node_id) -> str { } // FIXMEs are as per #2410 some(node_export(_, path)) { - #fmt["export %s (id=%?)", // FIXME: add more info here + #fmt["export %s (id=%?)", // add more info here path_to_str(*path), id] } - some(node_arg(_, _)) { // FIXME: add more info here + some(node_arg(_, _)) { // add more info here #fmt["arg (id=%?)", id] } - some(node_local(_)) { // FIXME: add more info here + some(node_local(_)) { // add more info here #fmt["local (id=%?)", id] } - some(node_ctor(*)) { // FIXME: add more info here + some(node_ctor(*)) { // add more info here #fmt["node_ctor (id=%?)", id] } - some(node_dtor(*)) { // FIXME: add more info here + some(node_dtor(*)) { // add more info here #fmt["node_dtor (id=%?)", id] } some(node_block(_)) { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 09bb2cc5409..8ce34a06329 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -159,7 +159,7 @@ fn is_exported(i: ident, m: _mod) -> bool { for variants.each {|v| if v.node.name == i { local = true; - parent_enum = some(/* FIXME: bad */ copy it.ident); + parent_enum = some(/* FIXME (#2543) */ copy it.ident); } } } @@ -268,7 +268,7 @@ pure fn is_unguarded(&&a: arm) -> bool { } pure fn unguarded_pat(a: arm) -> option<[@pat]> { - if is_unguarded(a) { some(/* FIXME: bad */ copy a.pats) } else { none } + if is_unguarded(a) { some(/* FIXME (#2543) */ copy a.pats) } else { none } } // Provides an extra node_id to hang callee information on, in case the @@ -278,8 +278,8 @@ fn op_expr_callee_id(e: @expr) -> node_id { e.id - 1 } pure fn class_item_ident(ci: @class_member) -> ident { alt ci.node { - instance_var(i,_,_,_,_) { /* FIXME: bad */ copy i } - class_method(it) { /* FIXME: bad */ copy it.ident } + instance_var(i,_,_,_,_) { /* FIXME (#2543) */ copy i } + class_method(it) { /* FIXME (#2543) */ copy it.ident } } } @@ -297,7 +297,7 @@ fn split_class_items(cs: [@class_member]) -> ([ivar], [@method]) { for cs.each {|c| alt c.node { instance_var(i, t, cm, id, vis) { - vs += [{ident: /* FIXME: bad */ copy i, + vs += [{ident: /* FIXME (#2543) */ copy i, ty: t, cm: cm, id: id, @@ -319,11 +319,11 @@ pure fn class_member_visibility(ci: @class_member) -> visibility { impl inlined_item_methods for inlined_item { fn ident() -> ident { alt self { - ii_item(i) { /* FIXME: bad */ copy i.ident } - ii_native(i) { /* FIXME: bad */ copy i.ident } - ii_method(_, m) { /* FIXME: bad */ copy m.ident } - ii_ctor(_, nm, _, _) { /* FIXME: bad */ copy nm } - ii_dtor(_, nm, _, _) { /* FIXME: bad */ copy nm } + ii_item(i) { /* FIXME (#2543) */ copy i.ident } + ii_native(i) { /* FIXME (#2543) */ copy i.ident } + ii_method(_, m) { /* FIXME (#2543) */ copy m.ident } + ii_ctor(_, nm, _, _) { /* FIXME (#2543) */ copy nm } + ii_dtor(_, nm, _, _) { /* FIXME (#2543) */ copy nm } } } @@ -480,12 +480,17 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(id); }, - visit_fn: fn@(fk: visit::fn_kind, d: fn_decl, - _b: blk, _sp: span, id: node_id) { + visit_fn: fn@(fk: visit::fn_kind, d: ast::fn_decl, + _b: ast::blk, _sp: span, id: ast::node_id) { vfn(id); alt fk { - visit::fk_ctor(_, tps, self_id, parent_id) | + visit::fk_ctor(nm, tps, self_id, parent_id) { + vec::iter(tps) {|tp| vfn(tp.id)} + vfn(id); + vfn(self_id); + vfn(parent_id.node); + } visit::fk_dtor(tps, self_id, parent_id) { vec::iter(tps) {|tp| vfn(tp.id)} vfn(id); @@ -500,7 +505,11 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(m.self_id); vec::iter(tps) {|tp| vfn(tp.id)} } - visit::fk_anon(*) | visit::fk_fn_block(*) { + visit::fk_anon(_, capture_clause) + | visit::fk_fn_block(capture_clause) { + for vec::each(*capture_clause) {|clause| + vfn(clause.id); + } } } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 5dfe40b7ee0..fb9560065a8 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -91,9 +91,9 @@ fn get_attr_name(attr: ast::attribute) -> ast::ident { // All "bad" FIXME copies are as per #2543 fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident { alt meta.node { - ast::meta_word(n) { /* FIXME bad */ copy n } - ast::meta_name_value(n, _) { /* FIXME bad */ copy n } - ast::meta_list(n, _) { /* FIXME bad */ copy n } + ast::meta_word(n) { /* FIXME (#2543) */ copy n } + ast::meta_name_value(n, _) { /* FIXME (#2543) */ copy n } + ast::meta_list(n, _) { /* FIXME (#2543) */ copy n } } } @@ -120,7 +120,7 @@ fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@str> { #[doc = "Gets a list of inner meta items from a list meta_item type"] fn get_meta_item_list(meta: @ast::meta_item) -> option<[@ast::meta_item]> { alt meta.node { - ast::meta_list(_, l) { option::some(/* FIXME bad */ copy l) } + ast::meta_list(_, l) { option::some(/* FIXME (#2543) */ copy l) } _ { option::none } } } @@ -266,15 +266,15 @@ fn last_meta_item_list_by_name( /* Higher-level applications */ -// FIXME: This needs to sort by meta_item variant in addition to the item name -// (See [Fixme-sorting]) +// FIXME (#607): This needs to sort by meta_item variant in addition to +// the item name (See [Fixme-sorting]) fn sort_meta_items(+items: [@ast::meta_item]) -> [@ast::meta_item] { fn lteq(&&ma: @ast::meta_item, &&mb: @ast::meta_item) -> bool { fn key(m: @ast::meta_item) -> ast::ident { alt m.node { - ast::meta_word(name) { /* FIXME bad */ copy name } - ast::meta_name_value(name, _) { /* FIXME bad */ copy name } - ast::meta_list(name, _) { /* FIXME bad */ copy name } + ast::meta_word(name) { /* FIXME (#2543) */ copy name } + ast::meta_name_value(name, _) { /* FIXME (#2543) */ copy name } + ast::meta_list(name, _) { /* FIXME (#2543) */ copy name } } } ret key(ma) <= key(mb); @@ -292,7 +292,7 @@ fn remove_meta_items_by_name(items: [@ast::meta_item], name: ast::ident) -> ret vec::filter_map(items, { |item| if get_meta_item_name(item) != name { - option::some(/* FIXME bad */ copy item) + option::some(/* FIXME (#2543) */ copy item) } else { option::none } @@ -317,7 +317,7 @@ linkage fn find_linkage_metas(attrs: [ast::attribute]) -> [@ast::meta_item] { find_linkage_attrs(attrs).flat_map {|attr| alt check attr.node.value.node { - ast::meta_list(_, items) { /* FIXME bad */ copy items } + ast::meta_list(_, items) { /* FIXME (#2543) */ copy items } } } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 97911f9d8b8..49560fb5bbd 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -123,7 +123,7 @@ fn lookup_char_pos_adj(map: codemap, pos: uint) let loc = lookup_char_pos(map, pos); alt (loc.file.substr) { fss_none { - {filename: /* FIXME bad */ copy loc.file.name, + {filename: /* FIXME (#2543) */ copy loc.file.name, line: loc.line, col: loc.col, file: some(loc.file)} @@ -132,7 +132,7 @@ fn lookup_char_pos_adj(map: codemap, pos: uint) lookup_char_pos_adj(map, sp.lo + (pos - loc.file.start_pos.ch)) } fss_external(eloc) { - {filename: /* FIXME bad */ copy eloc.filename, + {filename: /* FIXME (#2543) */ copy eloc.filename, line: eloc.line + loc.line - 1u, col: if loc.line == 1u {eloc.col + loc.col} else {loc.col}, file: none} @@ -178,7 +178,7 @@ type file_lines = {file: filemap, lines: [uint]}; fn span_to_filename(sp: span, cm: codemap::codemap) -> filename { let lo = lookup_char_pos(cm, sp.lo); - ret /* FIXME bad */ copy lo.file.name; + ret /* FIXME (#2543) */ copy lo.file.name; } fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines { diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index b65c6524d12..b8ebb27f51b 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -201,7 +201,7 @@ fn highlight_lines(cm: codemap::codemap, sp: span, // arbitrarily only print up to six lines of the error let max_lines = 6u; let mut elided = false; - let mut display_lines = /* FIXME bad */ copy lines.lines; + let mut display_lines = /* FIXME (#2543) */ copy lines.lines; if vec::len(display_lines) > max_lines { display_lines = vec::slice(display_lines, 0u, max_lines); elided = true; diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index ebb56fa3b58..26a906f8cf0 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -11,8 +11,8 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "env"); - // FIXME: if this was more thorough it would manufacture an - // option rather than just an maybe-empty string. (Issue #2248) + // FIXME (#2248): if this was more thorough it would manufacture an + // option rather than just an maybe-empty string. let var = expr_to_str(cx, args[0], "#env requires a string"); alt os::getenv(var) { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ba44404fe24..26313e97494 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -109,10 +109,10 @@ fn new_span(cx: ext_ctxt, sp: span) -> span { ret {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()}; } -// FIXME: this is a terrible kludge to inject some macros into the default -// compilation environment. When the macro-definition system is substantially -// more mature, these should move from here, into a compiled part of libcore -// at very least. (Issue #2247) +// FIXME (#2247): this is a terrible kludge to inject some macros into +// the default compilation environment. When the macro-definition system +// is substantially more mature, these should move from here, into a +// compiled part of libcore at very least. fn core_macros() -> str { ret diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 5ea8b677675..0cc4ba0a570 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -30,11 +30,10 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, ret pieces_to_expr(cx, sp, pieces, args); } -// FIXME: A lot of these functions for producing expressions can probably -// be factored out in common with other code that builds expressions. -// FIXME: Cleanup the naming of these functions +// FIXME (#2249): A lot of these functions for producing expressions can +// probably be factored out in common with other code that builds +// expressions. Also: Cleanup the naming of these functions. // NOTE: Moved many of the common ones to build.rs --kevina -// See Issue #2249 fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr]) -> @ast::expr { fn make_path_vec(_cx: ext_ctxt, ident: ast::ident) -> [ast::ident] { diff --git a/src/libsyntax/ext/qquote.rs b/src/libsyntax/ext/qquote.rs index 9830c379ef6..3f3eb001250 100644 --- a/src/libsyntax/ext/qquote.rs +++ b/src/libsyntax/ext/qquote.rs @@ -104,8 +104,8 @@ fn gather_anti_quotes(lo: uint, node: N) -> aq_ctxt with *default_visitor()}; let cx = @{lo:lo, gather: dvec()}; node.visit(cx, mk_vt(v)); - // FIXME: Maybe this is an overkill (merge_sort), it might be better - // to just keep the gather array in sorted order ... (Issue #2250) + // FIXME (#2250): Maybe this is an overkill (merge_sort), it might + // be better to just keep the gather array in sorted order. cx.gather.swap { |v| vec::to_mut(std::sort::merge_sort({|a,b| a.lo < b.lo}, v)) }; diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs index bf3014d1621..4dad13dc06a 100644 --- a/src/libsyntax/ext/simplext.rs +++ b/src/libsyntax/ext/simplext.rs @@ -466,8 +466,7 @@ fn p_t_s_rec(cx: ext_ctxt, m: matchable, s: selector, b: binders) { } } } - /* FIXME: handle embedded types and blocks, at least - (Issue #2251) */ + /* FIXME (#2251): handle embedded types and blocks, at least */ expr_mac(mac) { p_t_s_r_mac(cx, mac, s, b); } @@ -722,8 +721,8 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, [@{params: pattern_to_selectors(cx, arg), body: elts[1u]}]; - // FIXME: check duplicates (or just simplify - // the macro arg situation) (Issue #2251) + // FIXME (#2251): check duplicates (or just simplify + // the macro arg situation) } _ { cx.span_bug(mac.span, "undocumented invariant in \ diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 0589e48489c..ff296eb5aad 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -88,11 +88,12 @@ fn fold_meta_item_(&&mi: @meta_item, fld: ast_fold) -> @meta_item { meta_word(id) { meta_word(fld.fold_ident(id)) } meta_list(id, mis) { let fold_meta_item = {|x|fold_meta_item_(x, fld)}; - meta_list(/* FIXME: bad */ copy id, + meta_list(/* FIXME: (#2543) */ copy id, vec::map(mis, fold_meta_item)) } meta_name_value(id, s) { - meta_name_value(fld.fold_ident(id), /* FIXME: bad */ copy s) + meta_name_value(fld.fold_ident(id), + /* FIXME (#2543) */ copy s) } }, span: fld.new_span(mi.span)}; @@ -123,8 +124,8 @@ fn fold_mac_(m: mac, fld: ast_fold) -> mac { mac_embed_type(ty) { mac_embed_type(fld.fold_ty(ty)) } mac_embed_block(blk) { mac_embed_block(fld.fold_block(blk)) } mac_ellipsis { mac_ellipsis } - mac_aq(_,_) { /* FIXME: bad */ copy m.node } - mac_var(_) { /* FIXME: bad */ copy m.node } + mac_aq(_,_) { /* FIXME (#2543) */ copy m.node } + mac_var(_) { /* FIXME (#2543) */ copy m.node } }, span: fld.new_span(m.span)}; } @@ -145,7 +146,7 @@ fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound { } fn fold_ty_param(tp: ty_param, fld: ast_fold) -> ty_param { - {ident: /* FIXME: bad */ copy tp.ident, + {ident: /* FIXME (#2543) */ copy tp.ident, id: fld.new_id(tp.id), bounds: @vec::map(*tp.bounds, {|x|fold_ty_param_bound(x, fld)})} } @@ -168,12 +169,12 @@ fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) -> crate_directive_ { ret alt cd { cdir_src_mod(id, attrs) { - cdir_src_mod(fld.fold_ident(id), /* FIXME: bad */ copy attrs) + cdir_src_mod(fld.fold_ident(id), /* FIXME (#2543) */ copy attrs) } cdir_dir_mod(id, cds, attrs) { cdir_dir_mod(fld.fold_ident(id), vec::map(cds, fld.fold_crate_directive), - /* FIXME: bad */ copy attrs) + /* FIXME (#2543) */ copy attrs) } cdir_view_item(vi) { cdir_view_item(fld.fold_view_item(vi)) } cdir_syntax(_) { copy cd } @@ -181,7 +182,7 @@ fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) -> } fn noop_fold_view_item(vi: view_item_, _fld: ast_fold) -> view_item_ { - ret /* FIXME: bad */ copy vi; + ret /* FIXME (#2543) */ copy vi; } @@ -223,8 +224,8 @@ fn noop_fold_class_item(&&ci: @class_member, fld: ast_fold) -> @class_member { @{node: alt ci.node { instance_var(ident, t, cm, id, p) { - instance_var(/* FIXME: bad */ copy ident, fld.fold_ty(t), cm, id, - p) + instance_var(/* FIXME (#2543) */ copy ident, + fld.fold_ty(t), cm, id, p) } class_method(m) { class_method(fld.fold_method(m)) } }, @@ -260,7 +261,7 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { id: dtor_id with dtor.node} with dtor}}; item_class( - /* FIXME: bad */ copy typms, + /* FIXME (#2543) */ copy typms, vec::map(ifaces, {|p| fold_iface_ref(p, fld) }), vec::map(items, fld.fold_class_item), {node: {body: ctor_body, @@ -278,7 +279,7 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { item_iface(tps, rp, methods) { item_iface(fold_ty_params(tps, fld), rp, - /* FIXME: bad */ copy methods) + /* FIXME (#2543) */ copy methods) } item_res(decl, typms, body, did, cid, rp) { item_res(fold_fn_decl(decl, fld), @@ -297,7 +298,7 @@ fn fold_iface_ref(&&p: @iface_ref, fld: ast_fold) -> @iface_ref { fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method { ret @{ident: fld.fold_ident(m.ident), - attrs: /* FIXME: bad */ copy m.attrs, + attrs: /* FIXME (#2543) */ copy m.attrs, tps: fold_ty_params(m.tps, fld), decl: fold_fn_decl(m.decl, fld), body: fld.fold_block(m.body), @@ -344,7 +345,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ { pat_rec(fields, etc) { let mut fs = []; for fields.each {|f| - fs += [{ident: /* FIXME: bad */ copy f.ident, + fs += [{ident: /* FIXME (#2543) */ copy f.ident, pat: fld.fold_pat(f.pat)}]; } pat_rec(fs, etc) @@ -507,13 +508,13 @@ fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { } fn noop_fold_constr(c: constr_, fld: ast_fold) -> constr_ { - {path: fld.fold_path(c.path), args: /* FIXME: bad */ copy c.args, + {path: fld.fold_path(c.path), args: /* FIXME (#2543) */ copy c.args, id: fld.new_id(c.id)} } fn noop_fold_ty_constr(c: ty_constr_, fld: ast_fold) -> ty_constr_ { let rslt: ty_constr_ = - {path: fld.fold_path(c.path), args: /* FIXME: bad */ copy c.args, + {path: fld.fold_path(c.path), args: /* FIXME (#2543) */ copy c.args, id: fld.new_id(c.id)}; rslt } @@ -542,7 +543,7 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { some(e) {some(fld.fold_expr(e))} none {none} }; - ret {name: /* FIXME: bad */ copy v.name, + ret {name: /* FIXME (#2543) */ copy v.name, attrs: attrs, args: args, id: fld.new_id(v.id), disr_expr: de, @@ -550,7 +551,7 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { } fn noop_fold_ident(&&i: ident, _fld: ast_fold) -> ident { - ret /* FIXME: bad */ copy i; + ret /* FIXME (#2543) */ copy i; } fn noop_fold_path(&&p: path, fld: ast_fold) -> path { @@ -644,7 +645,7 @@ impl of ast_fold for ast_fold_precursor { fn fold_class_item(&&ci: @class_member) -> @class_member { @{node: alt ci.node { instance_var(nm, t, mt, id, p) { - instance_var(/* FIXME: bad */ copy nm, + instance_var(/* FIXME (#2543) */ copy nm, (self as ast_fold).fold_ty(t), mt, id, p) } class_method(m) { diff --git a/src/libsyntax/parse.rs b/src/libsyntax/parse.rs index 4ebdd0dd5b5..d062f4bde6d 100644 --- a/src/libsyntax/parse.rs +++ b/src/libsyntax/parse.rs @@ -17,7 +17,7 @@ import attr::parser_attr; import common::parser_common; import ast::node_id; import util::interner; -// FIXME: resolve badness +// FIXME (#1935): resolve badness import lexer::*;//{string_reader_as_reader, tt_reader_as_reader, //reader, string_reader, tt_reader}; import diagnostic::{span_handler, mk_span_handler, mk_handler, emitter}; @@ -75,7 +75,7 @@ fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg, let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr); sess.chpos = rdr.chpos; sess.byte_pos = sess.byte_pos + rdr.pos; - let cx = @{sess: sess, cfg: /* FIXME: bad */ copy p.cfg}; + let cx = @{sess: sess, cfg: /* FIXME (#2543) */ copy p.cfg}; let (companionmod, _) = path::splitext(path::basename(input)); let (m, attrs) = eval::eval_crate_directives_to_mod( cx, cdirs, prefix, option::some(companionmod)); @@ -85,7 +85,7 @@ fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg, {directives: cdirs, module: m, attrs: crate_attrs + attrs, - config: /* FIXME: bad */ copy p.cfg}); + config: /* FIXME (#2543) */ copy p.cfg}); } fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg, diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 69aa4775e43..f1415cb9e20 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -203,7 +203,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler, let {tok: tok, sp: sp} = rdr.next_token(); if token::is_lit(tok) { let s = get_str_from(rdr, bstart); - literals += [{lit: s, pos: sp.lo}]; + vec::push(literals, {lit: s, pos: sp.lo}); log(debug, "tok lit: " + s); } else { log(debug, "tok: " + token::to_str(*rdr.interner, tok)); diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index f8292be51fe..52cb9366df8 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -93,8 +93,8 @@ impl parser_common for parser { fn eat_keyword(word: str) -> bool { self.require_keyword(word); - // FIXME: this gratuitous use of @ is to - // workaround LLVM bug #13042 + // FIXME (#13042): this gratuitous use of @ is to + // workaround LLVM bug. alt @self.token { @token::IDENT(sid, false) { if str::eq(word, *self.get_str(sid)) { @@ -159,7 +159,7 @@ impl parser_common for parser { else { self.expect(t); } } _ { } } - v += [f(self)]; + vec::push(v, f(self)); } ret v; @@ -202,7 +202,7 @@ impl parser_common for parser { _ { } } if sep.trailing_sep_allowed && self.token == ket { break; } - v += [f(self)]; + vec::push(v, f(self)); } ret v; } diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs index 5ef8417ec6f..ae11c883443 100644 --- a/src/libsyntax/parse/eval.rs +++ b/src/libsyntax/parse/eval.rs @@ -103,7 +103,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); let i = p0.mk_item(cdir.span.lo, cdir.span.hi, - /* FIXME: bad */ copy id, + /* FIXME (#2543) */ copy id, ast::item_mod(m0), ast::public, mod_attrs); // Thread defids, chpos and byte_pos through the parsers cx.sess.chpos = r0.chpos; @@ -119,7 +119,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, let (m0, a0) = eval_crate_directives_to_mod( cx, cdirs, full_path, none); let i = - @{ident: /* FIXME: bad */ copy id, + @{ident: /* FIXME (#2543) */ copy id, attrs: attrs + a0, id: cx.sess.next_id, node: ast::item_mod(m0), diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 14cb8b41473..02b34e8dc86 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -154,7 +154,7 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token::token, sp: span} { ret ret_val; } tt_frame_up(option::some(tt_f)) { - r.cur <- tt_f; + r.cur = tt_f; /* the above `if` would need to be a `while` if we didn't know that the last thing in a `tt_delim` is always a `tt_flat` */ r.cur.idx += 1u; @@ -414,9 +414,9 @@ fn scan_number(c: char, rdr: string_reader) -> token::token { bump(rdr); ret token::LIT_FLOAT(intern(*rdr.interner, @num_str), ast::ty_f64); - /* FIXME: if this is out of range for either a 32-bit or - 64-bit float, it won't be noticed till the back-end (Issue #2252) - */ + /* FIXME (#2252): if this is out of range for either a + 32-bit or 64-bit float, it won't be noticed till the + back-end. */ } else { is_float = true; } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 146c3ab3de9..46e838fd4be 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -17,10 +17,10 @@ import dvec::{dvec, extensions}; export file_type; export parser; -// FIXME: #ast expects to find this here but it's actually defined in `parse` -// Fixing this will be easier when we have export decls on individual items -- -// then parse can export this publicly, and everything else crate-visibly. -// (See #1893) +// FIXME (#1893): #ast expects to find this here but it's actually +// defined in `parse` Fixing this will be easier when we have export +// decls on individual items -- then parse can export this publicly, and +// everything else crate-visibly. import parse_from_source_str; export parse_from_source_str; @@ -172,10 +172,10 @@ class parser { {mode: mode, ty: p.parse_ty(false), ident: name, id: p.get_id()} }; - // FIXME: constrs is empty because right now, higher-order functions - // can't have constrained types. - // Not sure whether that would be desirable anyway. See #34 for the - // story on constrained types. + // FIXME (#34): constrs is empty because right now, higher-order + // functions can't have constrained types. Not sure whether + // that would be desirable anyway. See bug for the story on + // constrained types. let constrs: [@constr] = []; let (ret_style, ret_ty) = self.parse_ret_ty(); ret {inputs: inputs, output: ret_ty, @@ -2039,7 +2039,7 @@ class parser { } fn parse_ctor(result_ty: ast::ty_) -> class_contents { - // Can ctors/dtors have attrs? FIXME + // FIXME (#2660): Can ctors/dtors have attrs? let lo = self.last_span.lo; let (decl_, _) = self.parse_fn_decl(impure_fn, {|p| p.parse_arg()}); let decl = {output: @{id: self.get_id(), @@ -2050,7 +2050,7 @@ class parser { } fn parse_dtor() -> class_contents { - // Can ctors/dtors have attrs? FIXME + // FIXME (#2660): Can ctors/dtors have attrs? let lo = self.last_span.lo; let body = self.parse_block(); dtor_decl(body, mk_sp(lo, self.last_span.hi)) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6bd9e79b727..89f3b2d3aba 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -545,12 +545,11 @@ fn print_item(s: ps, &&item: @ast::item) { } for items.each {|ci| /* - FIXME: collect all private items and print them - in a single "priv" section + FIXME (#1893): collect all private items and print + them in a single "priv" section tjc: I'm not going to fix this yet b/c we might change how exports work, including for class items - (see #1893) */ hardbreak_if_not_bol(s); maybe_print_comment(s, ci.span.lo); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3b5b73d78de..5d27ee1452f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -28,7 +28,7 @@ enum fn_kind { fn name_of_fn(fk: fn_kind) -> ident { alt fk { fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _, _) - | fk_ctor(name, _, _, _) { /* FIXME: bad */ copy name } + | fk_ctor(name, _, _, _) { /* FIXME (#2543) */ copy name } fk_anon(*) | fk_fn_block(*) { @"anon" } fk_dtor(*) { @"drop" } } @@ -38,7 +38,7 @@ fn tps_of_fn(fk: fn_kind) -> [ty_param] { alt fk { fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps, _) | fk_ctor(_, tps, _, _) | fk_dtor(tps, _, _) { - /* FIXME: bad */ copy tps + /* FIXME (#2543) */ copy tps } fk_anon(*) | fk_fn_block(*) { [] } } @@ -117,8 +117,8 @@ fn visit_item(i: @item, e: E, v: vt) { alt i.node { item_const(t, ex) { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); } item_fn(decl, tp, body) { - v.visit_fn(fk_item_fn(/* FIXME: bad */ copy i.ident, - /* FIXME: bad */ copy tp), decl, body, + v.visit_fn(fk_item_fn(/* FIXME (#2543) */ copy i.ident, + /* FIXME (#2543) */ copy tp), decl, body, i.span, i.id, e, v); } item_mod(m) { v.visit_mod(m, i.span, i.id, e, v); } @@ -131,8 +131,8 @@ fn visit_item(i: @item, e: E, v: vt) { v.visit_ty_params(tps, e, v); } item_res(decl, tps, body, dtor_id, _, rp) { - v.visit_fn(fk_res(/* FIXME: bad */ copy i.ident, - /* FIXME: bad */ copy tps, + v.visit_fn(fk_res(/* FIXME (#2543) */ copy i.ident, + /* FIXME (#2543) */ copy tps, rp), decl, body, i.span, dtor_id, e, v); } @@ -287,15 +287,16 @@ fn visit_fn_decl(fd: fn_decl, e: E, v: vt) { // because it is not a default impl of any method, though I doubt that really // clarifies anything. - Niko fn visit_method_helper(m: @method, e: E, v: vt) { - v.visit_fn(fk_method(/* FIXME: bad */ copy m.ident, - /* FIXME: bad */ copy m.tps, m), + v.visit_fn(fk_method(/* FIXME (#2543) */ copy m.ident, + /* FIXME (#2543) */ copy m.tps, m), m.decl, m.body, m.span, m.id, e, v); } // Similar logic to the comment on visit_method_helper - Tim fn visit_class_ctor_helper(ctor: class_ctor, nm: ident, tps: [ty_param], parent_id: def_id, e: E, v: vt) { - v.visit_fn(fk_ctor(/* FIXME: bad */ copy nm, /* FIXME: bad */ copy tps, + v.visit_fn(fk_ctor(/* FIXME (#2543) */ copy nm, + /* FIXME (#2543) */ copy tps, ctor.node.self_id, parent_id), ctor.node.dec, ctor.node.body, ctor.span, ctor.node.id, e, v) @@ -303,7 +304,7 @@ fn visit_class_ctor_helper(ctor: class_ctor, nm: ident, tps: [ty_param], fn visit_class_dtor_helper(dtor: class_dtor, tps: [ty_param], parent_id: def_id, e: E, v: vt) { - v.visit_fn(fk_dtor(/* FIXME: bad */ copy tps, dtor.node.self_id, + v.visit_fn(fk_dtor(/* FIXME (#2543) */ copy tps, dtor.node.self_id, parent_id), ast_util::dtor_dec(), dtor.node.body, dtor.span, dtor.node.id, e, v) diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S index d1433213b2d..7f2205b573a 100644 --- a/src/rt/arch/i386/morestack.S +++ b/src/rt/arch/i386/morestack.S @@ -213,15 +213,6 @@ MORESTACK: popl %ebp - // FIXME: I don't think these rules are necessary - // since the unwinder should never encounter an instruction - // pointer pointing here. -#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) - // Restore the rule for how to find %ebp - .cfi_restore %ebp - // Tell the unwinder how to find the CFA in terms of %esp - .cfi_def_cfa %esp, 16 -#endif retl $8 .L$bail: diff --git a/src/rt/arch/x86_64/morestack.S b/src/rt/arch/x86_64/morestack.S index 84340d26791..4ae21a3c4f6 100644 --- a/src/rt/arch/x86_64/morestack.S +++ b/src/rt/arch/x86_64/morestack.S @@ -51,7 +51,7 @@ MORESTACK: subq $184, %rsp - // FIXME: libgcc also saves rax. not sure if we need to + // FIXME: libgcc also saves rax. not sure if we need to (#2685) // Save argument registers of the original function movq %rdi, (%rsp) @@ -133,11 +133,6 @@ MORESTACK: popq %rax // Restore the return value popq %rbp - // FIXME: I don't think these rules are necessary - // since the unwinder should never encounter an instruction - // pointer pointing here. - .cfi_restore %rbp - .cfi_def_cfa %rsp, 16 ret .cfi_endproc diff --git a/src/rt/memory_region.h b/src/rt/memory_region.h index 145020e3cca..be8689672a8 100644 --- a/src/rt/memory_region.h +++ b/src/rt/memory_region.h @@ -2,8 +2,8 @@ * The Rust runtime uses memory regions to provide a primitive level of * memory management and isolation between tasks, and domains. * - * FIXME: Implement a custom lock-free malloc / free instead of relying solely - * on the standard malloc / free. + * FIXME (#2686): Implement a custom lock-free malloc / free instead of + * relying solely on the standard malloc / free. */ #ifndef MEMORY_REGION_H diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 7efc3b8839c..67b3bf84938 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -68,7 +68,7 @@ command_line_args : public kernel_owned // A global that indicates whether Rust typestate claim statements should be // executed Generated code will read this variable directly (I think). -// FIXME: This belongs somewhere else +// FIXME (#2670): This belongs somewhere else int check_claims = 0; /** diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index bc215c4e7b2..cab1b6b427c 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -232,7 +232,7 @@ rand_free(randctx *rctx) { /* Debug helpers strictly to verify ABI conformance. * - * FIXME: move these into a testcase when the testsuite + * FIXME (#2665): move these into a testcase when the testsuite * understands how to have explicit C files included. */ @@ -288,18 +288,20 @@ debug_opaque(type_desc *t, uint8_t *front) { rust_task *task = rust_get_current_task(); LOG(task, stdlib, "debug_opaque"); debug_tydesc_helper(t); - // FIXME may want to actually account for alignment. `front` may not - // indeed be the front byte of the passed-in argument. + // FIXME (#2667) may want to actually account for alignment. + // `front` may not indeed be the front byte of the passed-in + // argument. for (uintptr_t i = 0; i < t->size; ++front, ++i) { LOG(task, stdlib, " byte %" PRIdPTR ": 0x%" PRIx8, i, *front); } } -// FIXME this no longer reflects the actual structure of boxes! +// FIXME (#2667) this no longer reflects the actual structure of boxes! struct rust_box { RUST_REFCOUNTED(rust_box) - // FIXME `data` could be aligned differently from the actual box body data + // FIXME (#2667) `data` could be aligned differently from the actual + // box body data uint8_t data[]; }; @@ -635,7 +637,7 @@ extern "C" CDECL rust_task* rust_new_task_in_sched(rust_sched_id id) { rust_task *task = rust_get_current_task(); rust_scheduler *sched = task->kernel->get_scheduler_by_id(id); - // FIXME: What if we didn't get the scheduler? + // FIXME (#2668): What if we didn't get the scheduler? return new_task_common(sched, task); } diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp index e75ec46522f..ed31ddd9dad 100644 --- a/src/rt/rust_cc.cpp +++ b/src/rt/rust_cc.cpp @@ -79,7 +79,7 @@ class irc : public shape::data { shape::ptr data_end = sub.end_dp = shape::ptr(data_range.second); while (sub.dp < data_end) { sub.walk_reset(); - // FIXME: shouldn't this be 'sub.align = true;'? + // FIXME (#2669): shouldn't this be 'sub.align = true;'? align = true; } } @@ -214,7 +214,7 @@ irc::walk_variant2(shape::tag_info &tinfo, uint32_t variant_id, variant_ptr_and_end) { irc sub(*this, variant_ptr_and_end.first); - assert(variant_id < 256); // FIXME: Temporary sanity check. + assert(variant_id < 256); // FIXME (#2666): Temporary sanity check. const uint8_t *variant_end = variant_ptr_and_end.second; while (sub.sp < variant_end) { @@ -329,7 +329,7 @@ class mark : public shape::data { return; if (data_range.second - data_range.first > 100000) - abort(); // FIXME: Temporary sanity check. + abort(); // FIXME (#2666): Temporary sanity check. mark sub(*this, shape::ptr(data_range.first)); shape::ptr data_end = sub.end_dp = shape::ptr(data_range.second); @@ -454,7 +454,7 @@ mark::walk_variant2(shape::tag_info &tinfo, uint32_t variant_id, variant_ptr_and_end) { mark sub(*this, variant_ptr_and_end.first); - assert(variant_id < 256); // FIXME: Temporary sanity check. + assert(variant_id < 256); // FIXME (#2666): Temporary sanity check. const uint8_t *variant_end = variant_ptr_and_end.second; while (sub.sp < variant_end) { @@ -550,7 +550,9 @@ maybe_cc(rust_task *task) { return; } - // FIXME: Needs a snapshot. + // FIXME (#1498): depressingly, due to alignment bugs the whole file is + // disabled presently unless you're doing testing. Remove the whole thing + // when we transition to using a visitor for GC/CC. #if 0 if (task->cc_counter++ > RUST_CC_FREQUENCY) { task->cc_counter = 0; diff --git a/src/rt/rust_debug.h b/src/rt/rust_debug.h index 40a4c28f052..68f9e3d4519 100644 --- a/src/rt/rust_debug.h +++ b/src/rt/rust_debug.h @@ -34,7 +34,7 @@ public: flag(const char *in_name) : name(in_name), valid(false) {} bool operator*() { - // FIXME: We ought to lock this. + // FIXME (#2689): We ought to lock this. if (!valid) { char *ev = getenv(name); value = ev && ev[0] != '\0' && ev[0] != '0'; diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index dc743aceef8..b13b1490c0f 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -184,23 +184,22 @@ rust_kernel::run() { return rval; } -// FIXME: Fix all these FIXMEs void rust_kernel::fail() { - // FIXME: On windows we're getting "Application has requested the - // Runtime to terminate it in an unusual way" when trying to shutdown - // cleanly. + // FIXME (#2671): On windows we're getting "Application has + // requested the Runtime to terminate it in an unusual way" when + // trying to shutdown cleanly. set_exit_status(PROC_FAIL_CODE); #if defined(__WIN32__) exit(rval); #endif // Copy the list of schedulers so that we don't hold the lock while // running kill_all_tasks. - // FIXME: There's a lot that happens under kill_all_tasks, and I don't - // know that holding sched_lock here is ok, but we need to hold the - // sched lock to prevent the scheduler from being destroyed while - // we are using it. Probably we need to make rust_scheduler atomicly - // reference counted. + // FIXME (#2671): There's a lot that happens under kill_all_tasks, + // and I don't know that holding sched_lock here is ok, but we need + // to hold the sched lock to prevent the scheduler from being + // destroyed while we are using it. Probably we need to make + // rust_scheduler atomicly reference counted. std::vector scheds; { scoped_lock with(sched_lock); @@ -210,9 +209,9 @@ rust_kernel::fail() { } } - // FIXME: This is not a foolproof way to kill all tasks while ensuring - // that no new tasks or schedulers are created in the meantime that - // keep the scheduler alive. + // FIXME (#2671): This is not a foolproof way to kill all tasks + // while ensuring that no new tasks or schedulers are created in the + // meantime that keep the scheduler alive. for (std::vector::iterator iter = scheds.begin(); iter != scheds.end(); iter++) { (*iter)->kill_all_tasks(); diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp index 774a549fe8b..5074b1f40c6 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -126,7 +126,7 @@ rust_log::trace_ln(rust_task *task, uint32_t level, char *message) { assert(!task->on_rust_stack() && "logging on rust stack"); } - // FIXME: The scheduler and task names used to have meaning, + // FIXME (#2672): The scheduler and task names used to have meaning, // but they are always equal to 'main' currently #if 0 @@ -233,8 +233,9 @@ void update_crate_map(const cratemap* map, log_directive* dirs, // First update log levels for this crate update_module_map(map->entries, dirs, n_dirs, n_matches); // Then recurse on linked crates - // FIXME this does double work in diamond-shaped deps. could keep - // a set of visited addresses, if it turns out to be actually slow + // FIXME (#2673) this does double work in diamond-shaped deps. could + // keep a set of visited addresses, if it turns out to be actually + // slow for (size_t i = 0; map->children[i]; i++) { update_crate_map(map->children[i], dirs, n_dirs, n_matches); } diff --git a/src/rt/rust_run_program.cpp b/src/rt/rust_run_program.cpp index 8d7396aab93..739527b84eb 100644 --- a/src/rt/rust_run_program.cpp +++ b/src/rt/rust_run_program.cpp @@ -160,7 +160,7 @@ rust_run_program(const char* argv[], for (int fd = getdtablesize() - 1; fd >= 3; fd--) close(fd); if (dir) { int result = chdir(dir); - // FIXME: need error handling + // FIXME (#2674): need error handling assert(!result && "chdir failed"); } @@ -178,7 +178,7 @@ rust_run_program(const char* argv[], extern "C" CDECL int rust_process_wait(int proc) { - // FIXME: stub; exists to placate linker. + // FIXME: stub; exists to placate linker. (#2692) return 0; } diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp index e6297ec475c..a69084fc3ad 100644 --- a/src/rt/rust_sched_loop.cpp +++ b/src/rt/rust_sched_loop.cpp @@ -134,7 +134,7 @@ rust_task * rust_sched_loop::schedule_task() { lock.must_have_lock(); assert(this); - // FIXME: in the face of failing tasks, this is not always right. + // FIXME: in the face of failing tasks, this is not always right. (#2695) // assert(n_live_tasks() > 0); if (running_tasks.length() > 0) { size_t k = isaac_rand(&rctx); diff --git a/src/rt/rust_sched_loop.h b/src/rt/rust_sched_loop.h index f8e52e0498b..61fd8ac05fd 100644 --- a/src/rt/rust_sched_loop.h +++ b/src/rt/rust_sched_loop.h @@ -87,10 +87,7 @@ public: memory_region local_region; randctx rctx; - - // FIXME: Neither of these are used - int32_t list_index; - const char *const name; + const char *const name; // Used for debugging // Only a pointer to 'name' is kept, so it must live as long as this // domain. diff --git a/src/rt/rust_scheduler.h b/src/rt/rust_scheduler.h index 199c5f4bf64..74e6d6bf2bd 100644 --- a/src/rt/rust_scheduler.h +++ b/src/rt/rust_scheduler.h @@ -16,7 +16,7 @@ class rust_sched_launcher; class rust_sched_launcher_factory; class rust_scheduler : public kernel_owned { - // FIXME: Make these private + // FIXME (#2693): Make these private public: rust_kernel *kernel; private: diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h index 5c83c997e2d..cfac33008b9 100644 --- a/src/rt/rust_shape.h +++ b/src/rt/rust_shape.h @@ -43,8 +43,6 @@ const uint8_t SHAPE_I64 = 7u; const uint8_t SHAPE_F32 = 8u; const uint8_t SHAPE_F64 = 9u; const uint8_t SHAPE_BOX = 10u; -// FIXME: remove after snapshot (6/18/12) -const uint8_t SHAPE_VEC = 11u; const uint8_t SHAPE_TAG = 12u; const uint8_t SHAPE_STRUCT = 17u; const uint8_t SHAPE_BOX_FN = 18u; @@ -86,7 +84,7 @@ public: template inline T *alloc(size_t count = 1) { - // FIXME: align + // FIXME: align (probably won't fix before #1498) size_t sz = count * sizeof(T); T *rv = (T *)ptr; ptr += sz; @@ -304,7 +302,6 @@ ctxt::walk() { case SHAPE_I64: WALK_NUMBER(int64_t); break; case SHAPE_F32: WALK_NUMBER(float); break; case SHAPE_F64: WALK_NUMBER(double); break; - case SHAPE_VEC: walk_vec0(); break; case SHAPE_TAG: walk_tag0(); break; case SHAPE_BOX: walk_box0(); break; case SHAPE_STRUCT: walk_struct0(); break; @@ -897,7 +894,8 @@ public: void walk_tag1(tag_info &tinfo); void walk_struct1(const uint8_t *end_sp) { - // FIXME: shouldn't we be aligning to the first element here? + // FIXME (probably won't fix before #1498): shouldn't we be aligning + // to the first element here? static_cast(this)->walk_struct2(end_sp); } diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 19785e3a24e..adbd75f1c90 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -59,7 +59,8 @@ rust_task::delete_this() DLOG(sched_loop, task, "~rust_task %s @0x%" PRIxPTR ", refcnt=%d", name, (uintptr_t)this, ref_count); - // FIXME: We should do this when the task exits, not in the destructor + // FIXME (#2677): We should do this when the task exits, not in the + // destructor { scoped_lock with(supervisor_lock); if (supervisor) { @@ -67,7 +68,7 @@ rust_task::delete_this() } } - /* FIXME: tighten this up, there are some more + /* FIXME (#2677): tighten this up, there are some more assertions that hold at task-lifecycle events. */ assert(ref_count == 0); // || // (ref_count == 1 && this == sched->root_task)); @@ -114,13 +115,14 @@ cleanup_task(cleanup_args *args) { } } - // FIXME: For performance we should do the annihilator instead - // of the cycle collector even under normal termination, but + // FIXME (#2676): For performance we should do the annihilator + // instead of the cycle collector even under normal termination, but // since that would hide memory management errors (like not derefing // boxes), it needs to be disableable in debug builds. if (threw_exception) { - // FIXME: When the annihilator is more powerful and successfully - // runs resource destructors, etc. we can get rid of this cc + // FIXME (#2676): When the annihilator is more powerful and + // successfully runs resource destructors, etc. we can get rid + // of this cc cc::do_cc(task); annihilate_boxes(task); } @@ -287,7 +289,7 @@ void rust_task::begin_failure(char const *expr, char const *file, size_t line) { if (expr) { - // FIXME: Change this message to be + // FIXME (#2678): Change this message to be // 'task failed at ...' LOG_ERR(this, task, "upcall fail '%s', %s:%" PRIdPTR, expr, file, line); @@ -301,7 +303,7 @@ rust_task::begin_failure(char const *expr, char const *file, size_t line) { #else die(); conclude_failure(); - // FIXME: Need unwinding on windows. This will end up aborting + // FIXME (#908): Need unwinding on windows. This will end up aborting sched_loop->fail(); #endif } @@ -458,7 +460,7 @@ rust_task::calloc(size_t size, const char *tag) { void rust_task::notify(bool success) { - // FIXME (1078) Do this in rust code + // FIXME (#1078) Do this in rust code if(notify_enabled) { rust_port *target_port = kernel->get_port_by_id(notify_port); @@ -622,7 +624,7 @@ rust_task::reset_stack_limit() { uintptr_t sp = get_sp(); // Have to do the rest on the C stack because it involves // freeing stack segments, logging, etc. - // FIXME: This probably doesn't need to happen on the C + // FIXME (#2679): This probably doesn't need to happen on the C // stack now reset_args ra = {this, sp}; call_on_c_stack(&ra, (void*)reset_stack_limit_on_c_stack); diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 43f1abd190e..2a58725c6a4 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -18,10 +18,11 @@ threads at any time. This may keep the task from being destroyed even after the task is dead from a Rust task lifecycle perspective. - FIXME: The task and the scheduler have an over-complicated, undocumented - protocol for shutting down the task, hopefully without races. It would be - easier to reason about if other runtime objects could not access the task - from arbitrary threads, and didn't need to be atomically refcounted. + FIXME (#2696): The task and the scheduler have an over-complicated, + undocumented protocol for shutting down the task, hopefully without + races. It would be easier to reason about if other runtime objects could + not access the task from arbitrary threads, and didn't need to be + atomically refcounted. */ #ifndef RUST_TASK_H @@ -42,8 +43,9 @@ // The amount of extra space at the end of each stack segment, available // to the rt, compiler and dynamic linker for running small functions -// FIXME: We want this to be 128 but need to slim the red zone calls down, -// disable lazy symbol relocation, and other things we haven't discovered yet +// FIXME (#1509): We want this to be 128 but need to slim the red zone calls +// down, disable lazy symbol relocation, and other things we haven't +// discovered yet #define RZ_LINUX_32 (1024*2) #define RZ_LINUX_64 (1024*2) #define RZ_MAC_32 (1024*20) @@ -303,7 +305,7 @@ public: void allow_kill(); }; -// FIXME: It would be really nice to be able to get rid of this. +// FIXME (#2697): It would be really nice to be able to get rid of this. inline void *operator new[](size_t size, rust_task *task, const char *tag) { return task->malloc(size, tag); } @@ -360,9 +362,9 @@ sanitize_next_sp(uintptr_t next_sp) { // to the amount of stack needed for calling __morestack I've added some // extra bytes here. - // FIXME: On the rust stack this potentially puts is quite far into the - // red zone. Might want to just allocate a new rust stack every time we - // switch back to rust. + // FIXME (#2698): On the rust stack this potentially puts is quite far + // into the red zone. Might want to just allocate a new rust stack every + // time we switch back to rust. const uintptr_t padding = 16; return align_down(next_sp - padding); @@ -416,7 +418,7 @@ rust_task::call_on_rust_stack(void *args, void *fn_ptr) { uintptr_t sp = sanitize_next_sp(next_rust_sp); - // FIXME(2047): There are times when this is called and needs + // FIXME (#2047): There are times when this is called and needs // to be able to throw, and we don't account for that. __morestack(args, fn_ptr, sp); @@ -529,7 +531,7 @@ rust_task::record_stack_limit() { inline rust_task* rust_get_current_task() { uintptr_t sp_limit = get_sp_limit(); - // FIXME (1226) - Because of a hack in upcall_call_shim_on_c_stack this + // FIXME (#1226) - Because of a hack in upcall_call_shim_on_c_stack this // value is sometimes inconveniently set to 0, so we can't use this // method of retreiving the task pointer and need to fall back to TLS. if (sp_limit == 0) diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 3bd705b6690..940cf3aa01a 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -49,7 +49,7 @@ extern "C" CDECL void upcall_call_shim_on_c_stack(void *args, void *fn_ptr) { rust_task *task = rust_get_current_task(); - // FIXME (1226) - The shim functions generated by rustc contain the + // FIXME (#1226) - The shim functions generated by rustc contain the // morestack prologue, so we need to let them know they have enough // stack. record_sp_limit(0); @@ -72,9 +72,9 @@ extern "C" CDECL void upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) { rust_task *task = rust_get_current_task(); - // FIXME: Because of the hack in the other function that disables the - // stack limit when entering the C stack, here we restore the stack limit - // again. + // FIXME (#2680): Because of the hack in the other function that disables + // the stack limit when entering the C stack, here we restore the stack + // limit again. task->record_stack_limit(); try { @@ -86,7 +86,7 @@ upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) { assert(false && "Rust task failed after reentering the Rust stack"); } - // FIXME: As above + // FIXME (#2680): As above record_sp_limit(0); } @@ -143,66 +143,46 @@ upcall_trace(char const *msg, * Allocate an object in the exchange heap */ -extern "C" CDECL uintptr_t -exchange_malloc(rust_task *task, type_desc *td, uintptr_t size) { - - LOG(task, mem, "upcall exchange malloc(0x%" PRIxPTR ")", td); - - size_t total_size = get_box_size(size, td->align); - void *p = task->kernel->calloc(total_size, "exchange malloc"); - - rust_opaque_box *header = static_cast(p); - header->ref_count = -1; // This is not ref counted - header->td = td; - header->prev = 0; - header->next = 0; - - return (uintptr_t)header; -} - -// FIXME: remove after snapshot (6/13/12) struct s_exchange_malloc_args { rust_task *task; uintptr_t retval; type_desc *td; -}; - -extern "C" CDECL void -upcall_s_exchange_malloc(s_exchange_malloc_args *args) { - rust_task *task = args->task; - LOG_UPCALL_ENTRY(task); - - args->retval = exchange_malloc(task, args->td, args->td->size); -} - -extern "C" CDECL uintptr_t -upcall_exchange_malloc(type_desc *td) { - rust_task *task = rust_get_current_task(); - s_exchange_malloc_args args = {task, 0, td}; - UPCALL_SWITCH_STACK(task, &args, upcall_s_exchange_malloc); - return args.retval; -} - -struct s_exchange_malloc_dyn_args { - rust_task *task; - uintptr_t retval; - type_desc *td; uintptr_t size; }; extern "C" CDECL void -upcall_s_exchange_malloc_dyn(s_exchange_malloc_dyn_args *args) { +upcall_s_exchange_malloc(s_exchange_malloc_args *args) { rust_task *task = args->task; LOG_UPCALL_ENTRY(task); + LOG(task, mem, "upcall exchange malloc(0x%" PRIxPTR ")", args->td); - args->retval = exchange_malloc(task, args->td, args->size); + size_t total_size = get_box_size(args->size, args->td->align); + // FIXME--does this have to be calloc? (Issue #2682) + void *p = task->kernel->calloc(total_size, "exchange malloc"); + + rust_opaque_box *header = static_cast(p); + header->ref_count = -1; // This is not ref counted + header->td = args->td; + header->prev = 0; + header->next = 0; + + args->retval = (uintptr_t)header; } +extern "C" CDECL uintptr_t +upcall_exchange_malloc(type_desc *td, uintptr_t size) { + rust_task *task = rust_get_current_task(); + s_exchange_malloc_args args = {task, 0, td, size}; + UPCALL_SWITCH_STACK(task, &args, upcall_s_exchange_malloc); + return args.retval; +} + +// FIXME (#2681): remove after snapshot (6/21/12) extern "C" CDECL uintptr_t upcall_exchange_malloc_dyn(type_desc *td, uintptr_t size) { rust_task *task = rust_get_current_task(); - s_exchange_malloc_dyn_args args = {task, 0, td, size}; - UPCALL_SWITCH_STACK(task, &args, upcall_s_exchange_malloc_dyn); + s_exchange_malloc_args args = {task, 0, td, size}; + UPCALL_SWITCH_STACK(task, &args, upcall_s_exchange_malloc); return args.retval; } @@ -229,69 +209,49 @@ upcall_exchange_free(void *ptr) { * Allocate an object in the task-local heap. */ -extern "C" CDECL uintptr_t -shared_malloc(rust_task *task, type_desc *td, uintptr_t size) { - LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", td); - - cc::maybe_cc(task); - - // FIXME--does this have to be calloc? - rust_opaque_box *box = task->boxed.calloc(td, size); - void *body = box_body(box); - - debug::maybe_track_origin(task, box); - - LOG(task, mem, - "upcall malloc(0x%" PRIxPTR ") = box 0x%" PRIxPTR - " with body 0x%" PRIxPTR, - td, (uintptr_t)box, (uintptr_t)body); - - return (uintptr_t)box; -} - -// FIXME: remove after snapshot (6/13/12) struct s_malloc_args { rust_task *task; uintptr_t retval; type_desc *td; -}; - -extern "C" CDECL void -upcall_s_malloc(s_malloc_args *args) { - rust_task *task = args->task; - LOG_UPCALL_ENTRY(task); - - args->retval = shared_malloc(task, args->td, args->td->size); -} - -extern "C" CDECL uintptr_t -upcall_malloc(type_desc *td) { - rust_task *task = rust_get_current_task(); - s_malloc_args args = {task, 0, td}; - UPCALL_SWITCH_STACK(task, &args, upcall_s_malloc); - return args.retval; -} - -struct s_malloc_dyn_args { - rust_task *task; - uintptr_t retval; - type_desc *td; uintptr_t size; }; extern "C" CDECL void -upcall_s_malloc_dyn(s_malloc_dyn_args *args) { +upcall_s_malloc(s_malloc_args *args) { rust_task *task = args->task; LOG_UPCALL_ENTRY(task); + LOG(task, mem, "upcall malloc(0x%" PRIxPTR ")", args->td); - args->retval = shared_malloc(task, args->td, args->size); + cc::maybe_cc(task); + + // FIXME--does this have to be calloc? (Issue #2682) + rust_opaque_box *box = task->boxed.calloc(args->td, args->size); + void *body = box_body(box); + + debug::maybe_track_origin(task, box); + + LOG(task, mem, + "upcall malloc(0x%" PRIxPTR ") = box 0x%" PRIxPTR + " with body 0x%" PRIxPTR, + args->td, (uintptr_t)box, (uintptr_t)body); + + args->retval = (uintptr_t)box; } +extern "C" CDECL uintptr_t +upcall_malloc(type_desc *td, uintptr_t size) { + rust_task *task = rust_get_current_task(); + s_malloc_args args = {task, 0, td, size}; + UPCALL_SWITCH_STACK(task, &args, upcall_s_malloc); + return args.retval; +} + +// FIXME (#2681): remove after snapshot (6/21/12) extern "C" CDECL uintptr_t upcall_malloc_dyn(type_desc *td, uintptr_t size) { rust_task *task = rust_get_current_task(); - s_malloc_dyn_args args = {task, 0, td, size}; - UPCALL_SWITCH_STACK(task, &args, upcall_s_malloc_dyn); + s_malloc_args args = {task, 0, td, size}; + UPCALL_SWITCH_STACK(task, &args, upcall_s_malloc); return args.retval; } diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index 2040a641c47..247f253fd9f 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -111,7 +111,7 @@ make_str_vec(rust_kernel* kernel, size_t nstrs, char **strs) { inline size_t get_box_size(size_t body_size, size_t body_align) { size_t header_size = sizeof(rust_opaque_box); - // FIXME: This alignment calculation is suspicious. Is it right? + // FIXME (#2699): This alignment calculation is suspicious. Is it right? size_t total_size = align_to(header_size, body_align) + body_size; return total_size; } diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp index ccc762c2cc9..9558aaa7c06 100644 --- a/src/rt/sync/lock_and_signal.cpp +++ b/src/rt/sync/lock_and_signal.cpp @@ -9,7 +9,8 @@ * if you're using a pthreads cvar+mutex pair. */ -// FIXME: This is not a portable way of specifying an invalid pthread_t +// FIXME (#2683): This is not a portable way of specifying an invalid +// pthread_t #define INVALID_THREAD 0 diff --git a/src/rt/sync/lock_free_queue.h b/src/rt/sync/lock_free_queue.h index 3ee15d5d3a6..ed11b1aa321 100644 --- a/src/rt/sync/lock_free_queue.h +++ b/src/rt/sync/lock_free_queue.h @@ -88,8 +88,8 @@ class lock_free_queue { pointer_t *oldValue, pointer_t newValue) { - // FIXME this is requiring us to pass -fno-strict-aliasing to GCC - // (possibly there are other, similar problems) + // FIXME (#2701) this is requiring us to pass -fno-strict-aliasing + // to GCC (possibly there are other, similar problems) if (sync::compare_and_swap( (uint64_t*) address, *(uint64_t*) oldValue, diff --git a/src/rt/sync/timer.cpp b/src/rt/sync/timer.cpp index 28ee6da2b62..0204517d512 100644 --- a/src/rt/sync/timer.cpp +++ b/src/rt/sync/timer.cpp @@ -10,7 +10,7 @@ uint64_t ns_per_s = 1000000000LL; timer::timer() { #if __WIN32__ _ticks_per_s = 0LL; - // FIXME: assert this works or have a workaround. + // FIXME (#2675): assert this works or have a workaround. QueryPerformanceFrequency((LARGE_INTEGER *)&_ticks_per_s); if (_ticks_per_s == 0LL) { _ticks_per_s = 1LL; diff --git a/src/rustc/back/link.rs b/src/rustc/back/link.rs index facb0bcda31..4875fbd69ca 100644 --- a/src/rustc/back/link.rs +++ b/src/rustc/back/link.rs @@ -85,13 +85,12 @@ mod write { } } if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); } - // FIXME: This is mostly a copy of the bits of opt's -O2 that are - // available in the C api. - // FIXME2: We might want to add optimization levels like -O1, -O2, + // FIXME (#2396): This is mostly a copy of the bits of opt's -O2 that + // are available in the C api. + // Also: We might want to add optimization levels like -O1, -O2, // -Os, etc - // FIXME3: Should we expose and use the pass lists used by the opt + // Also: Should we expose and use the pass lists used by the opt // tool? - // See #2396 if opts.optimize != 0u { let fpm = mk_pass_manager(); @@ -668,9 +667,8 @@ fn link_binary(sess: session, // Stack growth requires statically linking a __morestack function cc_args += ["-lmorestack"]; - // FIXME: At some point we want to rpath our guesses as to where + // FIXME (#2397): At some point we want to rpath our guesses as to where // native libraries might live, based on the addl_lib_search_paths - // #2397 cc_args += rpath::get_rpath_flags(sess, output); #debug("%s link args: %s", cc_prog, str::connect(cc_args, " ")); diff --git a/src/rustc/back/upcall.rs b/src/rustc/back/upcall.rs index e6a61a1d078..2cae381431d 100644 --- a/src/rustc/back/upcall.rs +++ b/src/rustc/back/upcall.rs @@ -10,9 +10,9 @@ import lib::llvm::{type_names, ModuleRef, ValueRef, TypeRef}; type upcalls = {_fail: ValueRef, trace: ValueRef, - malloc_dyn: ValueRef, + malloc: ValueRef, free: ValueRef, - exchange_malloc_dyn: ValueRef, + exchange_malloc: ValueRef, exchange_free: ValueRef, validate_box: ValueRef, mark: ValueRef, @@ -55,14 +55,14 @@ fn declare_upcalls(targ_cfg: @session::config, trace: dv("trace", [T_ptr(T_i8()), T_ptr(T_i8()), int_t]), - malloc_dyn: - nothrow(d("malloc_dyn", + malloc: + nothrow(d("malloc", [T_ptr(tydesc_type), int_t], T_ptr(T_i8()))), free: nothrow(dv("free", [T_ptr(T_i8())])), - exchange_malloc_dyn: - nothrow(d("exchange_malloc_dyn", + exchange_malloc: + nothrow(d("exchange_malloc", [T_ptr(tydesc_type), int_t], T_ptr(T_i8()))), exchange_free: diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index 2cd9c392ef4..553db7695a8 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -78,9 +78,9 @@ fn build_configuration(sess: session, argv0: str, input: input) -> // Convert strings provided as --cfg [cfgspec] into a crate_cfg fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg { - // FIXME: It would be nice to use the parser to parse all varieties of - // meta_item here. At the moment we just support the meta_word variant. - // #2399 + // FIXME (#2399): It would be nice to use the parser to parse all + // varieties of meta_item here. At the moment we just support the + // meta_word variant. let mut words = []; for cfgspecs.each {|s| words += [attr::mk_word_item(@s)]; } ret words; @@ -100,8 +100,7 @@ fn parse_input(sess: session, cfg: ast::crate_cfg, input: input) parse::parse_crate_from_file(file, cfg, sess.parse_sess) } str_input(src) { - // FIXME: Don't really want to box the source string - // #2319 + // FIXME (#2319): Don't really want to box the source string parse::parse_crate_from_source_str( anon_src(), @src, cfg, sess.parse_sess) } @@ -389,9 +388,10 @@ fn host_triple() -> str { // idea of the host triple is the same as for the set of libraries we've // actually built. We can't just take LLVM's host triple because they // normalize all ix86 architectures to i386. - // FIXME: Instead of grabbing the host triple we really should be - // grabbing (at compile time) the target triple that this rustc is - // built with and calling that (at runtime) the host triple. (#2400) + + // FIXME (#2400): Instead of grabbing the host triple we really should + // be grabbing (at compile time) the target triple that this rustc is + // built with and calling that (at runtime) the host triple. let ht = #env("CFG_HOST_TRIPLE"); ret if ht != "" { ht @@ -660,10 +660,10 @@ fn build_output_filenames(input: input, }; if sess.building_library { - // FIXME: We might want to warn here; we're actually not going to - // respect the user's choice of library name when it comes time to - // link, we'll be linking to lib--.so no - // matter what. (#2401) + // FIXME (#2401): We might want to warn here; we're actually not + // going to respect the user's choice of library name when it + // comes time to link, we'll be linking to + // lib--.so no matter what. } if odir != none { diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index def4c7d9a83..9645d919b04 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -32,7 +32,7 @@ const stats: uint = 16u; const no_asm_comments: uint = 32u; const no_verify: uint = 64u; const trace: uint = 128u; -// FIXME: This exists to transition to a Rust crate runtime +// FIXME (#2377): This exists to transition to a Rust crate runtime // It should be removed const no_rt: uint = 256u; diff --git a/src/rustc/front/test.rs b/src/rustc/front/test.rs index 473d25841b8..2c40db16a45 100644 --- a/src/rustc/front/test.rs +++ b/src/rustc/front/test.rs @@ -64,9 +64,10 @@ fn strip_test_functions(crate: @ast::crate) -> @ast::crate { fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { // Remove any defined main function from the AST so it doesn't clash with - // the one we're going to add. FIXME: This is sloppy. Instead we should - // have some mechanism to indicate to the translation pass which function - // we want to be main. (#2403) + // the one we're going to add. + + // FIXME (#2403): This is sloppy. Instead we should have some mechanism to + // indicate to the translation pass which function we want to be main. fn nomain(&&item: @ast::item) -> option<@ast::item> { alt item.node { ast::item_fn(_, _, _) { @@ -338,8 +339,8 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr { } // Produces a bare function that wraps the test function -// FIXME: This can go away once fn is the type of bare function -// (See #1281) + +// FIXME (#1281): This can go away once fn is the type of bare function. fn mk_test_wrapper(cx: test_ctxt, fn_path_expr: ast::expr, span: span) -> @ast::expr { diff --git a/src/rustc/metadata/creader.rs b/src/rustc/metadata/creader.rs index 97ccb1d3f24..c63d03ce239 100644 --- a/src/rustc/metadata/creader.rs +++ b/src/rustc/metadata/creader.rs @@ -261,8 +261,8 @@ fn resolve_crate_deps(e: env, cdata: @[u8]) -> cstore::cnum_map { none { #debug("need to load it"); // This is a new one so we've got to load it - // FIXME: Need better error reporting than just a bogus span - // #2404 + // FIXME (#2404): Need better error reporting than just a bogus + // span. let fake_span = ast_util::dummy_sp(); let local_cnum = resolve_crate(e, cname, cmetas, *dep.hash, fake_span); diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index e8e367656c1..7209d4e6731 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -433,8 +433,7 @@ fn item_impl_methods(cdata: cmd, item: ebml::doc, base_tps: uint) let m_did = parse_def_id(ebml::doc_data(doc)); let mth_item = lookup_item(m_did.node, cdata.data); rslt += [@{did: translate_def_id(cdata, m_did), - /* FIXME tjc: take a look at this, it may relate - to #2323 */ + /* FIXME (maybe #2323) tjc: take a look at this. */ n_tps: item_ty_param_count(mth_item) - base_tps, ident: item_name(mth_item)}]; } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index e8fb1a3596e..62c4a078952 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -1028,9 +1028,8 @@ fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) { // We're just going to write a list of crate 'name-hash-version's, with // the assumption that they are numbered 1 to n. - // FIXME: This is not nearly enough to support correct versioning + // FIXME (#2166): This is not nearly enough to support correct versioning // but is enough to get transitive crate dependencies working. - // See #2166 ebml_w.start_tag(tag_crate_deps); for get_ordered_deps(cstore).each {|dep| encode_crate_dep(ebml_w, dep); diff --git a/src/rustc/metadata/filesearch.rs b/src/rustc/metadata/filesearch.rs index a5cc6c28d53..eeb44f80fd7 100644 --- a/src/rustc/metadata/filesearch.rs +++ b/src/rustc/metadata/filesearch.rs @@ -1,6 +1,6 @@ // A module for searching for libraries -// FIXME: I'm not happy how this module turned out. Should probably -// just be folded into cstore. +// FIXME (#2658): I'm not happy how this module turned out. Should +// probably just be folded into cstore. import result::result; export filesearch; diff --git a/src/rustc/metadata/loader.rs b/src/rustc/metadata/loader.rs index 2cbf529ecf0..a5874aa29fa 100644 --- a/src/rustc/metadata/loader.rs +++ b/src/rustc/metadata/loader.rs @@ -125,8 +125,8 @@ fn crate_name_from_metas(metas: [@ast::meta_item]) -> @str { some(i) { alt attr::get_meta_item_value_str(i) { some(n) { n } - // FIXME: Probably want a warning here since the user - // is using the wrong type of meta item (#2406) + // FIXME (#2406): Probably want a warning here since the user + // is using the wrong type of meta item. _ { fail } } } diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index b275ebcb3ae..2fae0850187 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -66,8 +66,8 @@ type decode_ctxt = @{ type extended_decode_ctxt = @{ dcx: decode_ctxt, - from_id_range: id_range, - to_id_range: id_range + from_id_range: ast_util::id_range, + to_id_range: ast_util::id_range }; iface tr { @@ -86,9 +86,9 @@ fn encode_inlined_item(ecx: @e::encode_ctxt, ast_map::path_to_str(path), *ii.ident(), ebml_w.writer.tell()]; - let id_range = compute_id_range(ii); + let id_range = ast_util::compute_id_range_for_inlined_item(ii); ebml_w.wr_tag(c::tag_ast as uint) {|| - encode_id_range(ebml_w, id_range); + ast_util::serialize_id_range(ebml_w, id_range); encode_ast(ebml_w, simplify_ast(ii)); encode_side_tables_for_ii(ecx, maps, ebml_w, ii); } @@ -108,7 +108,8 @@ fn decode_inlined_item(cdata: cstore::crate_metadata, none { none } some(ast_doc) { #debug["> Decoding inlined fn: %s::?", ast_map::path_to_str(path)]; - let from_id_range = decode_id_range(ast_doc); + let ast_dsr = ebml::ebml_deserializer(ast_doc); + let from_id_range = ast_util::deserialize_id_range(ast_dsr); let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range); let xcx = @{dcx: dcx, from_id_range: from_id_range, @@ -136,178 +137,10 @@ fn decode_inlined_item(cdata: cstore::crate_metadata, // ______________________________________________________________________ // Enumerating the IDs which appear in an AST -type id_range = {min: ast::node_id, max: ast::node_id}; - -fn empty(range: id_range) -> bool { - range.min >= range.max -} - -fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) { - let visitor = visit::mk_simple_visitor(@{ - visit_mod: fn@(_m: ast::_mod, _sp: span, id: ast::node_id) { - vfn(id) - }, - - visit_view_item: fn@(vi: @ast::view_item) { - alt vi.node { - ast::view_item_use(_, _, id) { vfn(id) } - ast::view_item_import(vps) | ast::view_item_export(vps) { - vec::iter(vps) {|vp| - alt vp.node { - ast::view_path_simple(_, _, id) { vfn(id) } - ast::view_path_glob(_, id) { vfn(id) } - ast::view_path_list(_, _, id) { vfn(id) } - } - } - } - } - }, - - visit_native_item: fn@(ni: @ast::native_item) { - vfn(ni.id) - }, - - visit_item: fn@(i: @ast::item) { - vfn(i.id); - alt i.node { - ast::item_res(_, _, _, d_id, c_id, _) { vfn(d_id); vfn(c_id); } - ast::item_enum(vs, _, _) { for vs.each {|v| vfn(v.node.id); } } - _ {} - } - }, - - visit_local: fn@(l: @ast::local) { - vfn(l.node.id); - }, - - visit_block: fn@(b: ast::blk) { - vfn(b.node.id); - }, - - visit_stmt: fn@(s: @ast::stmt) { - vfn(ast_util::stmt_id(*s)); - }, - - visit_arm: fn@(_a: ast::arm) { }, - - visit_pat: fn@(p: @ast::pat) { - vfn(p.id) - }, - - visit_decl: fn@(_d: @ast::decl) { - }, - - visit_expr: fn@(e: @ast::expr) { - vfn(e.id); - alt e.node { - ast::expr_unary(*) | ast::expr_binary(*) | ast::expr_index(*) { - vfn(ast_util::op_expr_callee_id(e)); - } - _ { /* fallthrough */ } - } - }, - - visit_ty: fn@(t: @ast::ty) { - alt t.node { - ast::ty_path(_, id) { - vfn(id) - } - _ { /* fall through */ } - } - }, - - visit_ty_params: fn@(ps: [ast::ty_param]) { - vec::iter(ps) {|p| vfn(p.id) } - }, - - visit_constr: fn@(_p: @ast::path, _sp: span, id: ast::node_id) { - vfn(id); - }, - - visit_fn: fn@(fk: visit::fn_kind, d: ast::fn_decl, - _b: ast::blk, _sp: span, id: ast::node_id) { - vfn(id); - - alt fk { - visit::fk_ctor(nm, tps, self_id, parent_id) { - vec::iter(tps) {|tp| vfn(tp.id)} - vfn(id); - vfn(self_id); - vfn(parent_id.node); - } - visit::fk_dtor(tps, self_id, parent_id) { - vec::iter(tps) {|tp| vfn(tp.id)} - vfn(id); - vfn(self_id); - vfn(parent_id.node); - } - visit::fk_item_fn(_, tps) | - visit::fk_res(_, tps, _) { - vec::iter(tps) {|tp| vfn(tp.id)} - } - visit::fk_method(_, tps, m) { - vfn(m.self_id); - vec::iter(tps) {|tp| vfn(tp.id)} - } - visit::fk_anon(_, capture_clause) - | visit::fk_fn_block(capture_clause) { - for vec::each(*capture_clause) {|clause| - vfn(clause.id); - } - } - } - - vec::iter(d.inputs) {|arg| - vfn(arg.id) - } - }, - - visit_class_item: fn@(c: @ast::class_member) { - alt c.node { - ast::instance_var(_, _, _, id,_) { - vfn(id) - } - ast::class_method(_) { - } - } - } - }); - - item.accept((), visitor) -} - -fn compute_id_range(item: ast::inlined_item) -> id_range { - let min = @mut int::max_value; - let max = @mut int::min_value; - visit_ids(item) {|id| - *min = int::min(*min, id); - *max = int::max(*max, id + 1); - } - ret {min:*min, max:*max}; -} - -fn encode_id_range(ebml_w: ebml::writer, id_range: id_range) { - ebml_w.wr_tag(c::tag_id_range as uint) {|| - ebml_w.emit_tup(2u) {|| - ebml_w.emit_tup_elt(0u) {|| ebml_w.emit_int(id_range.min) } - ebml_w.emit_tup_elt(1u) {|| ebml_w.emit_int(id_range.max) } - } - } -} - -fn decode_id_range(par_doc: ebml::doc) -> id_range { - let range_doc = par_doc[c::tag_id_range]; - let dsr = ebml::ebml_deserializer(range_doc); - dsr.read_tup(2u) {|| - {min: dsr.read_tup_elt(0u) {|| dsr.read_int() }, - max: dsr.read_tup_elt(1u) {|| dsr.read_int() }} - } -} - fn reserve_id_range(sess: session, - from_id_range: id_range) -> id_range { + from_id_range: ast_util::id_range) -> ast_util::id_range { // Handle the case of an empty range: - if empty(from_id_range) { ret from_id_range; } + if ast_util::empty(from_id_range) { ret from_id_range; } let cnt = from_id_range.max - from_id_range.min; let to_id_min = sess.parse_sess.next_id; let to_id_max = sess.parse_sess.next_id + cnt; @@ -318,7 +151,7 @@ fn reserve_id_range(sess: session, impl translation_routines for extended_decode_ctxt { fn tr_id(id: ast::node_id) -> ast::node_id { // from_id_range should be non-empty - assert !empty(self.from_id_range); + assert !ast_util::empty(self.from_id_range); (id - self.from_id_range.min + self.to_id_range.min) } fn tr_def_id(did: ast::def_id) -> ast::def_id { @@ -749,12 +582,14 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, ebml_w: ebml::writer, ii: ast::inlined_item) { ebml_w.wr_tag(c::tag_table as uint) {|| - visit_ids(ii, fn@(id: ast::node_id, copy ebml_w) { - // Note: this will cause a copy of ebml_w, which is bad as - // it has mut fields. But I believe it's harmless since - // we generate balanced EBML. - encode_side_tables_for_id(ecx, maps, ebml_w, id) - }); + ast_util::visit_ids_for_inlined_item( + ii, + fn@(id: ast::node_id, copy ebml_w) { + // Note: this will cause a copy of ebml_w, which is bad as + // it has mut fields. But I believe it's harmless since + // we generate balanced EBML. + encode_side_tables_for_id(ecx, maps, ebml_w, id) + }); } } diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs index 2208409ab50..9818c1c648b 100644 --- a/src/rustc/middle/borrowck.rs +++ b/src/rustc/middle/borrowck.rs @@ -175,6 +175,7 @@ fn check_crate(tcx: ty::ctxt, let bccx = @{tcx: tcx, method_map: method_map, last_use_map: last_use_map, + binding_map: int_hash(), root_map: root_map(), mutbl_map: int_hash()}; @@ -189,6 +190,7 @@ fn check_crate(tcx: ty::ctxt, type borrowck_ctxt = @{tcx: ty::ctxt, method_map: typeck::method_map, last_use_map: liveness::last_use_map, + binding_map: binding_map, root_map: root_map, mutbl_map: mutbl_map}; @@ -208,6 +210,10 @@ type root_map_key = {id: ast::node_id, derefs: uint}; // this is used in trans for optimization purposes. type mutbl_map = std::map::hashmap; +// maps from each binding's id to the mutability of the location it +// points at. See gather_loan.rs for more detail (search for binding_map) +type binding_map = std::map::hashmap; + // Errors that can occur"] enum bckerr_code { err_mut_uniq, @@ -228,6 +234,7 @@ enum categorization { cat_rvalue, // result of eval'ing some misc expr cat_special(special_kind), // cat_local(ast::node_id), // local variable + cat_binding(ast::node_id), // pattern binding cat_arg(ast::node_id), // formal argument cat_stack_upvar(cmt), // upvar in stack closure cat_deref(cmt, uint, ptr_kind), // deref of a ptr @@ -381,6 +388,7 @@ impl to_str_methods for borrowck_ctxt { cat_stack_upvar(_) { "stack-upvar" } cat_rvalue { "rvalue" } cat_local(node_id) { #fmt["local(%d)", node_id] } + cat_binding(node_id) { #fmt["binding(%d)", node_id] } cat_arg(node_id) { #fmt["arg(%d)", node_id] } cat_deref(cmt, derefs, ptr) { #fmt["%s->(%s, %u)", self.cat_to_repr(cmt.cat), @@ -466,6 +474,7 @@ impl to_str_methods for borrowck_ctxt { cat_special(sk_heap_upvar) { "variable declared in an outer block" } cat_rvalue { "non-lvalue" } cat_local(_) { mut_str + " local variable" } + cat_binding(_) { "pattern binding" } cat_arg(_) { "argument" } cat_deref(_, _, pk) { #fmt["dereference of %s %s pointer", mut_str, self.pk_to_sigil(pk)] } diff --git a/src/rustc/middle/borrowck/categorization.rs b/src/rustc/middle/borrowck/categorization.rs index cdfb2a08c68..b7143706fc3 100644 --- a/src/rustc/middle/borrowck/categorization.rs +++ b/src/rustc/middle/borrowck/categorization.rs @@ -265,12 +265,16 @@ impl public_methods for borrowck_ctxt { mutbl:m, ty:expr_ty} } - ast::def_binding(vid) { - // no difference between a binding and any other local variable - // from out point of view, except that they are always immutable + ast::def_binding(pid) { + // bindings are "special" since they are implicit pointers. + + // lookup the mutability for this binding that we found in + // gather_loans when we categorized it + let mutbl = self.binding_map.get(pid); + @{id:id, span:span, - cat:cat_local(vid), lp:some(@lp_local(vid)), - mutbl:m_imm, ty:expr_ty} + cat:cat_binding(pid), lp:none, + mutbl:mutbl, ty:expr_ty} } } } diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index 572be4f2ac7..bae0f4648d2 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -47,6 +47,7 @@ fn check_loans(bccx: borrowck_ctxt, mut declared_purity: ast::impure_fn, mut fn_args: @[]}); let vt = visit::mk_vt(@{visit_expr: check_loans_in_expr, + visit_local: check_loans_in_local, visit_block: check_loans_in_block, visit_fn: check_loans_in_fn with *visit::default_visitor()}); @@ -419,6 +420,9 @@ impl methods for check_loan_ctxt { // rvalues, I guess. cat_special(sk_static_item) { } + cat_deref(_, _, unsafe_ptr) { + } + // Nothing else. _ { self.bccx.span_err( @@ -542,6 +546,18 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, #debug["purity on exit=%?", copy self.declared_purity]; } +fn check_loans_in_local(local: @ast::local, + &&self: check_loan_ctxt, + vt: visit::vt) { + alt local.node.init { + some({op: ast::init_move, expr: expr}) { + self.check_move_out(expr); + } + some({op: ast::init_assign, _}) | none {} + } + visit::visit_local(local, self, vt); +} + fn check_loans_in_expr(expr: @ast::expr, &&self: check_loan_ctxt, vt: visit::vt) { diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs index 87980bf7248..df46a4cef8f 100644 --- a/src/rustc/middle/borrowck/gather_loans.rs +++ b/src/rustc/middle/borrowck/gather_loans.rs @@ -85,12 +85,12 @@ fn req_loans_in_expr(ex: @ast::expr, // is mutable in the caller's frame, thus effectively // passing the buck onto us to enforce this) // - // FIXME---this handling is not really adequate. For - // example, if there is a type like, {f: [int]}, we - // will ignore it, but we ought to be requiring it to - // be immutable (whereas something like {f:int} would - // be fine). - // (See #2493) + // FIXME (#2493): this handling is not really adequate. + // For example, if there is a type like, {f: [int]}, we + // will ignore it, but we ought to be requiring it to be + // immutable (whereas something like {f:int} would be + // fine). + // alt opt_deref_kind(arg_ty.ty) { some(deref_ptr(region_ptr)) | @@ -130,7 +130,7 @@ fn req_loans_in_expr(ex: @ast::expr, // Here, in an overloaded operator, the call is this expression, // and hence the scope of the borrow is this call. // - // FIXME/NOT REALLY---technically we should check the other + // FIX? / NOT REALLY---technically we should check the other // argument and consider the argument mode. But how annoying. // And this problem when goes away when argument modes are // phased out. So I elect to leave this undone. @@ -364,6 +364,16 @@ impl methods for gather_loan_ctxt { // cat_discr in the method preserve(): let cmt1 = self.bccx.cat_discr(cmt, alt_id); let arm_scope = ty::re_scope(arm_id); + + // Remember the mutability of the location that this + // binding refers to. This will be used later when + // categorizing the binding. This is a bit of a hack that + // would be better fixed by #2329; in that case we could + // allow the user to specify if they want an imm, const, + // or mut binding, or else just reflect the mutability + // through the type of the region pointer. + self.bccx.binding_map.insert(pat.id, cmt1.mutbl); + self.guarantee_valid(cmt1, m_const, arm_scope); for o_pat.each { |p| diff --git a/src/rustc/middle/borrowck/loan.rs b/src/rustc/middle/borrowck/loan.rs index ee61dd9f0cf..bbeca851742 100644 --- a/src/rustc/middle/borrowck/loan.rs +++ b/src/rustc/middle/borrowck/loan.rs @@ -43,7 +43,7 @@ impl loan_methods for loan_ctxt { } alt cmt.cat { - cat_rvalue | cat_special(_) { + cat_binding(_) | cat_rvalue | cat_special(_) { // should never be loanable self.bccx.tcx.sess.span_bug( cmt.span, diff --git a/src/rustc/middle/borrowck/preserve.rs b/src/rustc/middle/borrowck/preserve.rs index 98c9109fe8e..cbe9c4e3a4a 100644 --- a/src/rustc/middle/borrowck/preserve.rs +++ b/src/rustc/middle/borrowck/preserve.rs @@ -29,6 +29,12 @@ impl public_methods for borrowck_ctxt { } ok(()) } + cat_binding(_) { + // Bindings are these kind of weird implicit pointers (cc + // #2329). We require (in gather_loans) that they be + // rooted in an immutable location. + ok(()) + } cat_arg(_) { // This can happen as not all args are lendable (e.g., && // modes). In that case, the caller guarantees stability. diff --git a/src/rustc/middle/const_eval.rs b/src/rustc/middle/const_eval.rs index 661ad87dfa8..26ffbdc0273 100644 --- a/src/rustc/middle/const_eval.rs +++ b/src/rustc/middle/const_eval.rs @@ -1,7 +1,7 @@ import syntax::ast::*; -// FIXME this doesn't handle big integer/float literals correctly (nor does -// the rest of our literal handling - issue #33) +// FIXME (#33): this doesn't handle big integer/float literals correctly +// (nor does the rest of our literal handling). enum const_val { const_float(f64), const_int(i64), diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index cc8b0383e36..9ad4009c513 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -1669,7 +1669,14 @@ impl check_methods for @liveness { #fmt["illegal move from field `%s`", *name]); ret; } - vk_local(*) | vk_self | vk_implicit_ret { + vk_self { + self.tcx.sess.span_err( + move_span, + "illegal move from self (cannot move out of a field of \ + self)"); + ret; + } + vk_local(*) | vk_implicit_ret { self.tcx.sess.span_bug( move_span, #fmt["illegal reader (%?) for `%?`", diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index fd0ecaa4fd5..0ae04c25ccd 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -215,9 +215,9 @@ fn iter_effective_import_paths(vi: ast::view_item, iter_export_paths(vi) {|vp| alt vp.node { ast::view_path_simple(_, _, _) { } - // FIXME: support uniform ident-list exports eventually; - // at the moment they have half a meaning as reaching into - // tags. (but also see #1893) + // FIXME (but also see #1893): support uniform ident-list exports + // eventually; at the moment they have half a meaning as reaching + // into tags. ast::view_path_list(_, _, _) {} ast::view_path_glob(_,_) { f(vp); @@ -573,7 +573,6 @@ fn visit_item_with_scope(e: @env, i: @ast::item, } ast::item_class(tps, ifaces, members, ctor, m_dtor, _) { v.visit_ty_params(tps, sc, v); - // Can maybe skip this now that we require self on class fields let class_scope = @cons(scope_item(i), sc); /* visit the constructor... */ let ctor_scope = @cons(scope_method(ctor.node.self_id, tps), @@ -1061,7 +1060,7 @@ fn lookup_in_scope(e: env, &&sc: scopes, sp: span, name: ident, ns: namespace, } ast::item_class(tps, _, members, ctor, _, _) { if ns == ns_type { - ret lookup_in_ty_params(e, name, tps); + ret lookup_in_ty_params(e, name, tps); } if ns == ns_val && name == it.ident { ret some(ast::def_fn(local_def(ctor.node.id), @@ -1317,13 +1316,14 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option { alt i.node { ast::item_const(*) { if ns == ns_val { - ret some(ast::def_const(local_def(i.id))); } - } - ast::item_fn(decl, _, _) { - if ns == ns_val { - ret some(ast::def_fn(local_def(i.id), decl.purity)); + ret some(ast::def_const(local_def(i.id))); } } + ast::item_fn(decl, _, _) { + if ns == ns_val { + ret some(ast::def_fn(local_def(i.id), decl.purity)); + } + } ast::item_mod(_) { if ns == ns_module { ret some(ast::def_mod(local_def(i.id))); } } @@ -1342,9 +1342,16 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option { _ { } } } - ast::item_class(*) { - if ns == ns_type { - ret some(ast::def_class(local_def(i.id))); + ast::item_class(_, _, _members, ct, _, _) { + alt ns { + ns_type { + ret some(ast::def_class(local_def(i.id))); + } + ns_val { + ret some(ast::def_fn(local_def(ct.node.id), + ast::impure_fn)); + } + ns_module { } } } ast::item_impl(*) { /* ??? */ } @@ -1653,14 +1660,6 @@ fn index_mod(md: ast::_mod) -> mod_index { ast::item_class(tps, _, items, ctor, _, _) { // add the class name itself add_to_index(index, it.ident, mie_item(it)); - // add the constructor decl - add_to_index(index, it.ident, - mie_item(@{ident: it.ident, attrs: [], - id: ctor.node.id, - node: - item_fn(ctor.node.dec, tps, ctor.node.body), - vis: ast::public, - span: ctor.node.body.span})); } } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 44bb515393e..d202ba7a123 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -356,9 +356,9 @@ fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap, let ccx = bcx.ccx(); let (mk_fn, upcall) = alt heap { - heap_shared { (ty::mk_imm_box, ccx.upcalls.malloc_dyn) } + heap_shared { (ty::mk_imm_box, ccx.upcalls.malloc) } heap_exchange { - (ty::mk_imm_uniq, ccx.upcalls.exchange_malloc_dyn ) + (ty::mk_imm_uniq, ccx.upcalls.exchange_malloc ) } }; @@ -754,7 +754,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id, // We have to cast v0 let classptr = GEPi(bcx, v0, [0u, 1u]); // Find and call the actual destructor - let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, substs.tps); + let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, some(class_did), + substs.tps); // The second argument is the "self" argument for drop let params = lib::llvm::fn_ty_param_tys (llvm::LLVMGetElementType @@ -829,7 +830,11 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { build_return(bcx); } -fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t]) +fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, + // Parent ID is an option because resources don't + // have one. We can make this a def_id when + // resources get removed. + opt_id: option, substs: [ty::t]) -> ValueRef { let _icx = ccx.insn_ctxt("trans_res_dtor"); if (substs.len() > 0u) { @@ -841,14 +846,27 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t]) } else if did.crate == ast::local_crate { get_item_val(ccx, did.node) } else { - let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn, - proto: ast::proto_bare, - inputs: [{mode: ast::expl(ast::by_ref), + alt opt_id { + some(parent_id) { + let tcx = ccx.tcx; + let name = csearch::get_symbol(ccx.sess.cstore, did); + let class_ty = ty::subst_tps(tcx, substs, + ty::lookup_item_type(tcx, parent_id).ty); + let llty = type_of_dtor(ccx, class_ty); + get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv, + llty) + } + none { + let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn, + proto: ast::proto_bare, + inputs: [{mode: ast::expl(ast::by_ref), ty: ty::mk_nil_ptr(ccx.tcx)}], output: ty::mk_nil(ccx.tcx), ret_style: ast::return_val, constraints: []}); - trans_external_path(ccx, did, fty) + trans_external_path(ccx, did, fty) + } + } } } @@ -862,7 +880,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id, with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) {|bcx| let valptr = GEPi(bcx, rs, [0u, 1u]); // Find and call the actual destructor. - let dtor_addr = get_res_dtor(ccx, did, tps); + let dtor_addr = get_res_dtor(ccx, did, none, tps); let args = [bcx.fcx.llretptr, null_env_ptr(bcx)]; // Kludge to work around the fact that we know the precise type of the // value here, but the dtor expects a type that might have opaque @@ -1336,10 +1354,10 @@ fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block { fn call_memmove(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef) { - // FIXME: Provide LLVM with better alignment information when the - // alignment is statically known (it must be nothing more than a constant - // int, or LLVM complains -- not even a constant element of a tydesc - // works). (Related to #1645, I think?) + // FIXME (Related to #1645, I think?): Provide LLVM with better + // alignment information when the alignment is statically known (it must + // be nothing more than a constant int, or LLVM complains -- not even a + // constant element of a tydesc works). let _icx = cx.insn_ctxt("call_memmove"); let ccx = cx.ccx(); let key = alt ccx.sess.targ_cfg.arch { @@ -1421,11 +1439,12 @@ fn copy_val_no_check(bcx: block, action: copy_action, dst: ValueRef, // This works like copy_val, except that it deinitializes the source. // Since it needs to zero out the source, src also needs to be an lval. -// FIXME: We always zero out the source. Ideally we would detect the +// FIXME (#839): We always zero out the source. Ideally we would detect the // case where a variable is always deinitialized by block exit and thus -// doesn't need to be dropped. (Issue #839) +// doesn't need to be dropped. fn move_val(cx: block, action: copy_action, dst: ValueRef, src: lval_result, t: ty::t) -> block { + let _icx = cx.insn_ctxt("move_val"); let mut src_val = src.val; let tcx = cx.tcx(); @@ -1633,8 +1652,8 @@ fn cast_shift_rhs(op: ast::binop, if lhs_sz < rhs_sz { trunc(rhs, lhs_llty) } else if lhs_sz > rhs_sz { - // FIXME: If shifting by negative values becomes not undefined - // then this is wrong. (See discussion at #1570) + // FIXME (See discussion at #1570): If shifting by negative + // values becomes not undefined then this is wrong. zext(rhs, lhs_llty) } else { rhs @@ -1758,17 +1777,29 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop, // A user-defined operator method alt bcx.ccx().maps.method_map.find(ex.id) { some(origin) { + let bcx = lhs_res.bcx; let callee_id = ast_util::op_expr_callee_id(ex); + #debug["user-defined method callee_id: %s", + ast_map::node_id_to_str(bcx.tcx().items, callee_id)]; let fty = node_id_type(bcx, callee_id); - ret trans_call_inner( + + let dty = expr_ty(bcx, dst); + let target = alloc_ty(bcx, dty); + + let bcx = trans_call_inner( bcx, ex.info(), fty, expr_ty(bcx, ex), {|bcx| - // FIXME provide the already-computed address, not the expr - // #2528 + // FIXME (#2528): provide the already-computed address, not + // the expr. impl::trans_method_callee(bcx, callee_id, dst, origin) }, - arg_exprs([src]), save_in(lhs_res.val)); + arg_exprs([src]), save_in(target)); + + ret move_val(bcx, DROP_EXISTING, lhs_res.val, + // FIXME (#2704): should kind be owned? + {bcx: bcx, val: target, kind: owned}, + dty); } _ {} } @@ -2304,14 +2335,14 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t], } } ast_map::node_dtor(_, dtor, _, pt) { - let parent_id = alt ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx, - dtor.node.self_id)) { - some(did) { did } - none { ccx.sess.span_bug(dtor.span, "Bad self ty in \ + let parent_id = alt ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx, + dtor.node.self_id)) { + some(did) { did } + none { ccx.sess.span_bug(dtor.span, "Bad self ty in \ dtor"); } - }; - trans_class_dtor(ccx, *pt, dtor.node.body, - dtor.node.id, psubsts, some(hash_id), parent_id) + }; + trans_class_dtor(ccx, *pt, dtor.node.body, + dtor.node.id, psubsts, some(hash_id), parent_id) } // Ugh -- but this ensures any new variants won't be forgotten ast_map::node_expr(*) { ccx.tcx.sess.bug("Can't monomorphize an expr") } @@ -3317,7 +3348,7 @@ fn need_invoke(bcx: block) -> bool { loop { alt cur.kind { block_scope(inf) { - for inf.cleanups.each {|cleanup| + for vec::each(inf.cleanups) {|cleanup| alt cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) { if cleanup_type == normal_exit_and_unwind { @@ -4728,9 +4759,9 @@ fn trans_enum_variant(ccx: @crate_ctxt, enum_id: ast::node_id, } -// FIXME: this should do some structural hash-consing to avoid -// duplicate constants. I think. Maybe LLVM has a magical mode -// that does so later on? (#2530) +// FIXME (#2530): this should do some structural hash-consing to avoid +// duplicate constants. I think. Maybe LLVM has a magical mode that does so +// later on? fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { let _icx = cx.insn_ctxt("trans_const_expr"); alt e.node { @@ -4832,9 +4863,9 @@ fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { ast_map::node_item(@{ node: ast::item_const(_, subexpr), _ }, _) { - // FIXME: Instead of recursing here to regenerate the values - // for other constants, we should just look up the - // already-defined value (#2530) + // FIXME (#2530): Instead of recursing here to regenerate + // the values for other constants, we should just look up + // the already-defined value. trans_const_expr(cx, subexpr) } _ { @@ -4930,15 +4961,15 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl, } fn trans_class_dtor(ccx: @crate_ctxt, path: path, - body: ast::blk, - dtor_id: ast::node_id, substs: option, - hash_id: option, parent_id: ast::def_id) + body: ast::blk, dtor_id: ast::node_id, + psubsts: option, + hash_id: option, parent_id: ast::def_id) -> ValueRef { let tcx = ccx.tcx; /* Look up the parent class's def_id */ let mut class_ty = ty::lookup_item_type(tcx, parent_id).ty; /* Substitute in the class type if necessary */ - option::iter(substs) {|ss| + option::iter(psubsts) {|ss| class_ty = ty::subst_tps(tcx, ss.tys, class_ty); } @@ -4947,7 +4978,9 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path, let lldty = T_fn([T_ptr(type_of(ccx, ty::mk_nil(tcx))), T_ptr(type_of(ccx, class_ty))], llvm::LLVMVoidType()); - let s = get_dtor_symbol(ccx, path, dtor_id); + + let s = get_dtor_symbol(ccx, path, dtor_id, psubsts); + /* Register the dtor as a function. It has external linkage */ let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty); lib::llvm::SetLinkage(lldecl, lib::llvm::ExternalLinkage); @@ -4959,7 +4992,7 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path, } /* Translate the dtor body */ trans_fn(ccx, path, ast_util::dtor_dec(), - body, lldecl, impl_self(class_ty), substs, dtor_id); + body, lldecl, impl_self(class_ty), psubsts, dtor_id); lldecl } @@ -5196,16 +5229,34 @@ fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path { } + [path_name(i.ident)] } -/* If there's already a symbol for the dtor with , return it; - otherwise, create one and register it, returning it as well */ -fn get_dtor_symbol(ccx: @crate_ctxt, path: path, id: ast::node_id) -> str { +/* If there's already a symbol for the dtor with and substs , + return it; otherwise, create one and register it, returning it as well */ +fn get_dtor_symbol(ccx: @crate_ctxt, path: path, id: ast::node_id, + substs: option) -> str { + let t = ty::node_id_to_type(ccx.tcx, id); alt ccx.item_symbols.find(id) { some(s) { s } + none if is_none(substs) { + let s = mangle_exported_name(ccx, + path + [path_name(@ccx.names("dtor"))], + t); + ccx.item_symbols.insert(id, s); + s + } none { - let s = mangle_exported_name(ccx, path + - [path_name(@ccx.names("dtor"))], ty::node_id_to_type(ccx.tcx, id)); - ccx.item_symbols.insert(id, s); - s + // Monomorphizing, so just make a symbol, don't add + // this to item_symbols + alt substs { + some(ss) { + let mono_ty = ty::subst_tps(ccx.tcx, ss.tys, t); + mangle_exported_name(ccx, path + + [path_name(@ccx.names("dtor"))], mono_ty) + } + none { + ccx.sess.bug(#fmt("get_dtor_symbol: not monomorphizing and \ + couldn't find a symbol for dtor %?", path)); + } + } } } } @@ -5289,7 +5340,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { let lldty = T_fn([T_ptr(type_of(ccx, ty::mk_nil(tcx))), T_ptr(type_of(ccx, class_ty))], llvm::LLVMVoidType()); - let s = get_dtor_symbol(ccx, *pt, dt.node.id); + let s = get_dtor_symbol(ccx, *pt, dt.node.id, none); /* Make the declaration for the dtor */ let llfn = decl_internal_cdecl_fn(ccx.llmod, s, lldty); diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index fd66b34c816..745c25f6f79 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -545,7 +545,7 @@ fn make_opaque_cbox_take_glue( let sz = Add(bcx, sz, shape::llsize_of(ccx, T_box_header(ccx))); // Allocate memory, update original ptr, and copy existing data - let malloc = ccx.upcalls.exchange_malloc_dyn; + let malloc = ccx.upcalls.exchange_malloc; let cbox_out = Call(bcx, malloc, [tydesc, sz]); let cbox_out = PointerCast(bcx, cbox_out, llopaquecboxty); call_memmove(bcx, cbox_out, cbox_in, sz); diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index f80dd130e0e..e90590f0228 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -522,7 +522,7 @@ fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::ty) option::none {} }*/ - /* FIXME I am disabling this code as part of the patch that moves + /* FIXME (#2012): disabled this code as part of the patch that moves * recognition of named builtin types into resolve. I tried to fix * it, but it seems to already be broken -- it's only called when * --xg is given, and compiling with --xg fails on trivial programs. @@ -531,8 +531,6 @@ fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::ty) * needed. It is only done to track spans, but you will not get the * right spans anyway -- types tend to refer to stuff defined * elsewhere, not be self-contained. - * - * See Issue #2012 */ fail; diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs index 28536282fad..fcc7f370f74 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -700,8 +700,8 @@ fn trans_native_mod(ccx: @crate_ctxt, } } - // FIXME this is very shaky and probably gets ABIs wrong all over - // the place (#2535) + // FIXME (#2535): this is very shaky and probably gets ABIs wrong all + // over the place fn build_direct_fn(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item, tys: @c_stack_tys, cc: lib::llvm::CallConv) { diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs index 9731c34fa82..740d53ed773 100644 --- a/src/rustc/middle/trans/reflect.rs +++ b/src/rustc/middle/trans/reflect.rs @@ -163,8 +163,8 @@ impl methods for reflector { self.visit("leave_tup", extra); } - // FIXME: fetch constants out of intrinsic:: for the numbers. - // (#2594) + // FIXME (#2594): fetch constants out of intrinsic:: for the + // numbers. ty::ty_fn(fty) { let pureval = alt fty.purity { ast::pure_fn { 0u } @@ -226,10 +226,10 @@ impl methods for reflector { self.visit("leave_class", extra); } - // FIXME: visiting all the variants in turn is probably - // not ideal. It'll work but will get costly on big enums. - // Maybe let the visitor tell us if it wants to visit only - // a particular variant? (#2595) + // FIXME (#2595): visiting all the variants in turn is probably + // not ideal. It'll work but will get costly on big enums. Maybe + // let the visitor tell us if it wants to visit only a particular + // variant? ty::ty_enum(did, substs) { let bcx = self.bcx; let tcx = bcx.ccx().tcx; diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs index 61f82997e93..f28d0b53e53 100644 --- a/src/rustc/middle/trans/shape.rs +++ b/src/rustc/middle/trans/shape.rs @@ -21,12 +21,14 @@ import std::map::hashmap; import ty_ctxt = middle::ty::ctxt; -type nominal_id = @{did: ast::def_id, tps: [ty::t]}; +type nominal_id = @{did: ast::def_id, parent_id: option, + tps: [ty::t]}; fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id, + parent_id: option, tps: [ty::t]) -> nominal_id { let tps_norm = tps.map { |t| ty::normalize_ty(tcx, t) }; - @{did: did, tps: tps_norm} + @{did: did, parent_id: parent_id, tps: tps_norm} } fn hash_nominal_id(&&ri: nominal_id) -> uint { @@ -233,7 +235,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] { tk_enum { [s_variant_enum_t(ccx.tcx)] } tk_newtype | tk_complex { let mut s = [shape_enum], id; - let nom_id = mk_nominal_id(ccx.tcx, did, substs.tps); + let nom_id = mk_nominal_id(ccx.tcx, did, none, substs.tps); alt ccx.shape_cx.tag_id_to_index.find(nom_id) { none { id = ccx.shape_cx.next_tag_id; @@ -335,7 +337,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] { else { [shape_struct] }; let mut sub = []; option::iter(m_dtor_did) {|dtor_did| - let ri = @{did: dtor_did, tps: tps}; + let ri = @{did: dtor_did, parent_id: some(did), tps: tps}; let id = interner::intern(ccx.shape_cx.resources, ri); add_u16(s, id as u16); @@ -362,7 +364,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] { for substs.tps.each() {|t| assert !ty::type_has_params(t); } let subt = ty::subst(ccx.tcx, substs, raw_subt); let tps = substs.tps; - let ri = @{did: did, tps: tps}; + let ri = @{did: did, parent_id: none, tps: tps}; let id = interner::intern(ccx.shape_cx.resources, ri); let mut s = [shape_res]; @@ -489,7 +491,7 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef { // Compute the minimum and maximum size and alignment for each // variant. // - // FIXME: We could do better here; e.g. we know that any + // NB: We could do better here; e.g. we know that any // variant that contains (T,T) must be as least as large as // any variant that contains just T. let mut ranges = []; @@ -498,7 +500,7 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef { let mut min_size = 0u, min_align = 0u; for vec::each(variant.args) {|elem_t| if ty::type_has_params(elem_t) { - // FIXME: We could do better here; this causes us to + // NB: We could do better here; this causes us to // conservatively assume that (int, T) has minimum size 0, // when in fact it has minimum size sizeof(int). bounded = false; @@ -597,7 +599,8 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef { for uint::range(0u, len) {|i| let ri = interner::get(ccx.shape_cx.resources, i); for ri.tps.each() {|s| assert !ty::type_has_params(s); } - dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.tps)]; + dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.parent_id, + ri.tps)]; } ret mk_global(ccx, "resource_shapes", C_struct(dtors), true); } @@ -696,7 +699,7 @@ fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { // Computes the static size of a enum, without using mk_tup(), which is // bad for performance. // -// FIXME: Migrate trans over to use this. +// NB: Migrate trans over to use this. // Computes the size of the data part of an enum. fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint { diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs index 1eca2db5e7d..d05629b990f 100644 --- a/src/rustc/middle/trans/tvec.rs +++ b/src/rustc/middle/trans/tvec.rs @@ -190,7 +190,7 @@ fn trans_evec(bcx: block, args: [@ast::expr], let lleltptr = InBoundsGEP(bcx, dataptr, [C_uint(ccx, i)]); bcx = base::trans_expr_save_in(bcx, e, lleltptr); add_clean_temp_mem(bcx, lleltptr, unit_ty); - temp_cleanups += [lleltptr]; + vec::push(temp_cleanups, lleltptr); i += 1u; } @@ -422,8 +422,9 @@ fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t, let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); // Calculate the last pointer address we want to handle. - // FIXME: Optimize this when the size of the unit type is statically - // known to not use pointer casts, which tend to confuse LLVM. (#2536) + // FIXME (#2536): Optimize this when the size of the unit type is + // statically known to not use pointer casts, which tend to confuse + // LLVM. let data_end_ptr = pointer_add(bcx, data_ptr, fill); // Now perform the iteration. diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index c0f3014cf96..dc8dc1b92cf 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -8,6 +8,7 @@ import std::map::hashmap; import ty::*; export type_of; +export type_of_dtor; export type_of_explicit_args; export type_of_fn_from_ty; export type_of_fn; @@ -251,3 +252,9 @@ fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str { ); } +fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef { + T_fn([T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), + T_ptr(type_of(ccx, self_ty))], + llvm::LLVMVoidType()) +} + diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 7f87c6f74e2..628d407fead 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -183,8 +183,8 @@ fn mark_for_expr(cx: ctx, e: @expr) { node_type_needs(cx, use_repr, val.id); } expr_index(base, _) | expr_field(base, _, _) { - // FIXME could be more careful and not count fields - // after the chosen field (#2537) + // FIXME (#2537): could be more careful and not count fields after + // the chosen field. let base_ty = ty::node_id_to_type(cx.ccx.tcx, base.id); type_needs(cx, use_repr, ty::type_autoderef(cx.ccx.tcx, base_ty)); diff --git a/src/rustc/middle/tstate/ann.rs b/src/rustc/middle/tstate/ann.rs index a6a46d1e222..f20ad0f73dc 100644 --- a/src/rustc/middle/tstate/ann.rs +++ b/src/rustc/middle/tstate/ann.rs @@ -243,8 +243,8 @@ fn trit_str(t: trit) -> str { alt t { dont_care { "?" } ttrue { "1" } tfalse { "0" } } } -// FIXME: Would be nice to have unit tests for some of these operations, as -// a step towards formalizing them more rigorously. #2538 +// FIXME (#2538): Would be nice to have unit tests for some of these +// operations, as a step towards formalizing them more rigorously. // // Local Variables: diff --git a/src/rustc/middle/tstate/annotate.rs b/src/rustc/middle/tstate/annotate.rs index be38692c49e..d20cbcfe4d4 100644 --- a/src/rustc/middle/tstate/annotate.rs +++ b/src/rustc/middle/tstate/annotate.rs @@ -7,16 +7,18 @@ import aux::{num_constraints, get_fn_info, crate_ctxt, add_node}; import ann::empty_ann; import pat_util::pat_binding_ids; -fn collect_ids_expr(e: @expr, rs: @mut [node_id]) { *rs += [e.id]; } +fn collect_ids_expr(e: @expr, rs: @mut [node_id]) { vec::push(*rs, e.id); } -fn collect_ids_block(b: blk, rs: @mut [node_id]) { *rs += [b.node.id]; } +fn collect_ids_block(b: blk, rs: @mut [node_id]) { + vec::push(*rs, b.node.id); +} fn collect_ids_stmt(s: @stmt, rs: @mut [node_id]) { alt s.node { stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) { #debug["node_id %s", int::str(id)]; #debug["%s", stmt_to_str(*s)]; - *rs += [id]; + vec::push(*rs, id); } } } diff --git a/src/rustc/middle/tstate/auxiliary.rs b/src/rustc/middle/tstate/auxiliary.rs index 1ccb19cd53f..5fb79dc1318 100644 --- a/src/rustc/middle/tstate/auxiliary.rs +++ b/src/rustc/middle/tstate/auxiliary.rs @@ -195,8 +195,8 @@ may be the operator in a "check" expression in the source. */ type constraint = { path: @path, - // FIXME: really only want it to be mut during collect_locals. - // freeze it after that. (#2539) + // FIXME (#2539): really only want it to be mut during + // collect_locals. freeze it after that. descs: @dvec }; @@ -494,9 +494,8 @@ fn constraints(fcx: fn_ctxt) -> [norm_constraint] { ret rslt; } -// FIXME -// Would rather take an immutable vec as an argument, -// should freeze it at some earlier point. (#2539) +// FIXME (#2539): Would rather take an immutable vec as an argument, +// should freeze it at some earlier point. fn match_args(fcx: fn_ctxt, occs: @dvec, occ: [@constr_arg_use]) -> uint { #debug("match_args: looking at %s", diff --git a/src/rustc/middle/tstate/states.rs b/src/rustc/middle/tstate/states.rs index 2948d097ab6..4883422a908 100644 --- a/src/rustc/middle/tstate/states.rs +++ b/src/rustc/middle/tstate/states.rs @@ -169,9 +169,9 @@ fn find_pre_post_state_call(fcx: fn_ctxt, pres: prestate, a: @expr, id: node_id, ops: [init_op], bs: [@expr], cf: ret_style) -> bool { let mut changed = find_pre_post_state_expr(fcx, pres, a); - // FIXME: This could be a typestate constraint (except we're - // not using them inside the compiler, I guess... see - // discussion at #2178) + // FIXME (#2178): This could be a typestate constraint (except we're + // not using them inside the compiler, I guess... see discussion in + // bug) if vec::len(bs) != vec::len(ops) { fcx.ccx.tcx.sess.span_bug(a.span, #fmt["mismatched arg lengths: \ diff --git a/src/rustc/middle/tstate/tritv.rs b/src/rustc/middle/tstate/tritv.rs index 546a8ae7deb..7bcc4840d25 100644 --- a/src/rustc/middle/tstate/tritv.rs +++ b/src/rustc/middle/tstate/tritv.rs @@ -25,10 +25,10 @@ export to_str; 01 = "this constraint is definitely true" 00 = "this constraint is definitely false" 11 should never appear - FIXME: typestate precondition (uncertain and val must + FIXME (#2178): typestate precondition (uncertain and val must have the same length; 11 should never appear in a given position) (except we're not putting typestate constraints in the compiler, as - per discussion at #2178). + per discussion at). */ type t = {uncertain: bitv::bitv, val: bitv::bitv, nbits: uint}; @@ -90,8 +90,8 @@ fn trit_or(a: trit, b: trit) -> trit { tfalse { alt b { ttrue { dont_care } - /* FIXME: ?????? - Again, unit tests would help here -- #2538 + /* FIXME (#2538): ?????? + Again, unit tests would help here */ _ { tfalse @@ -101,12 +101,11 @@ fn trit_or(a: trit, b: trit) -> trit { } } -// FIXME: This still seems kind of dodgy to me (that is, +// FIXME (#2538): This still seems kind of dodgy to me (that is, // that 1 + ? = 1. But it might work out given that // all variables start out in a 0 state. Probably I need // to make it so that all constraints start out in a 0 state // (we consider a constraint false until proven true), too. -// #2538 would help. fn trit_and(a: trit, b: trit) -> trit { alt a { dont_care { b } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 92ed7da8ace..3083563d220 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -1209,7 +1209,6 @@ pure fn type_is_scalar(ty: t) -> bool { } } -// FIXME maybe inline this for speed? fn type_is_immediate(ty: t) -> bool { ret type_is_scalar(ty) || type_is_boxed(ty) || type_is_unique(ty) || type_is_region_ptr(ty); @@ -1614,7 +1613,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind { param_bounds_to_kind(cx.ty_param_bounds.get(did.node)) } ty_constr(t, _) { type_kind(cx, t) } - // FIXME: is self ever const? + // FIXME (#2663): is self ever const? ty_self { kind_noncopyable() } ty_var(_) | ty_var_integral(_) { cx.sess.bug("Asked to compute kind of a type variable"); @@ -2038,7 +2037,6 @@ fn hash_type_structure(st: sty) -> uint { fn hash_type_constr(id: uint, c: @type_constr) -> uint { let mut h = id; h = (h << 2u) + hash_def(h, c.node.id); - // FIXME this makes little sense for c.node.args.each {|a| alt a.node { carg_base { h += h << 2u; } @@ -2169,7 +2167,6 @@ fn args_eq(eq: fn(T, T) -> bool, fn constr_eq(c: @constr, d: @constr) -> bool { fn eq_int(&&x: uint, &&y: uint) -> bool { ret x == y; } ret path_to_str(c.node.path) == path_to_str(d.node.path) && - // FIXME: hack args_eq(eq_int, c.node.args, d.node.args); } diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 3d2dca700c2..3c7bddc9022 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -188,33 +188,29 @@ fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty { fn require_same_types( tcx: ty::ctxt, + maybe_infcx: option, span: span, t1: ty::t, t2: ty::t, msg: fn() -> str) -> bool { - alt infer::compare_tys(tcx, t1, t2) { - result::ok(()) { true } - result::err(terr) { - tcx.sess.span_err(span, msg() + ": " + - ty::type_err_to_str(tcx, terr)); - false + let l_tcx, l_infcx; + alt maybe_infcx { + none { + l_tcx = tcx; + l_infcx = infer::new_infer_ctxt(tcx); + } + some(i) { + l_tcx = i.tcx; + l_infcx = i; } } -} -fn require_same_types_in_infcx( - infcx: infer::infer_ctxt, - span: span, - t1: ty::t, - t2: ty::t, - msg: fn() -> str) -> bool { - - alt infer::compare_tys_in_infcx(infcx, t1, t2) { + alt infer::mk_eqty(l_infcx, t1, t2) { result::ok(()) { true } result::err(terr) { - infcx.tcx.sess.span_err(span, msg() + ": " + - ty::type_err_to_str(infcx.tcx, terr)); + l_tcx.sess.span_err(span, msg() + ": " + + ty::type_err_to_str(l_tcx, terr)); false } } diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index de12fcb389a..e3f6ba40aef 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -74,7 +74,7 @@ import rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope}; import rscope::{in_binding_rscope, region_scope, type_rscope}; import syntax::ast::ty_i; import typeck::infer::{unify_methods}; // infcx.set() -import typeck::infer::{force_level, force_none, force_non_region_vars_only, +import typeck::infer::{force_level, force_none, force_ty_vars_only, force_all}; type fn_ctxt = @@ -606,14 +606,6 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> ty::t { }; } -// Returns true if the two types unify and false if they don't. -fn are_compatible(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) -> bool { - alt fcx.mk_eqty(expected, actual) { - result::ok(_) { ret true; } - result::err(_) { ret false; } - } -} - // AST fragment checking fn check_lit(fcx: @fn_ctxt, lit: @ast::lit) -> ty::t { let tcx = fcx.ccx.tcx; @@ -929,22 +921,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let lhs_t = fcx.expr_ty(lhs); let lhs_t = structurally_resolved_type(fcx, lhs.span, lhs_t); ret alt (op, ty::get(lhs_t).struct) { - (ast::add, ty::ty_vec(lhs_mt)) { - // For adding vectors with type L=[ML TL] and R=[MR TR], the the - // result [ML T] where TL <: T and TR <: T. In other words, the - // result type is (generally) the LUB of (TL, TR) and takes the - // mutability from the LHS. - let t_var = fcx.infcx.next_ty_var(); - let const_vec_t = ty::mk_vec(tcx, {ty: t_var, - mutbl: ast::m_const}); - demand::suptype(fcx, lhs.span, const_vec_t, lhs_t); - let rhs_bot = check_expr_with(fcx, rhs, const_vec_t); - let result_vec_t = ty::mk_vec(tcx, {ty: t_var, - mutbl: lhs_mt.mutbl}); - fcx.write_ty(expr.id, result_vec_t); - lhs_bot | rhs_bot - } - (_, _) if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) { // Shift is a special case: rhs can be any integral type @@ -1198,14 +1174,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, } } ast::neg { - // If the operand's type is an integral type variable, we - // don't want to resolve it yet, because the rest of the - // typing context might not have had the opportunity to - // constrain it yet. - if !(ty::type_is_var_integral(oprnd_t)) { - oprnd_t = structurally_resolved_type(fcx, oprnd.span, - oprnd_t); - } + oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t); if !(ty::type_is_integral(oprnd_t) || ty::type_is_fp(oprnd_t)) { oprnd_t = check_user_unop(fcx, "-", "unary-", expr, @@ -1248,9 +1217,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, }; alt expr_opt { none { - if !are_compatible(fcx, ret_ty, ty::mk_nil(tcx)) { + alt fcx.mk_eqty(ret_ty, ty::mk_nil(tcx)) { + result::ok(_) { /* fall through */ } + result::err(_) { tcx.sess.span_err(expr.span, - "ret; in function returning non-nil"); + "ret; in function returning non-nil"); } } } some(e) { check_expr_with(fcx, e, ret_ty); } @@ -2138,7 +2109,7 @@ fn instantiate_path(fcx: @fn_ctxt, // resolution is possible, then an error is reported. fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t { alt infer::resolve_shallow(fcx.infcx, tp, - force_non_region_vars_only) { + force_ty_vars_only) { result::ok(t_s) if !ty::type_is_var(t_s) { ret t_s; } _ { fcx.ccx.tcx.sess.span_fatal @@ -2305,7 +2276,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) { expected %u", i_n_tps, n_tps)); } else { require_same_types( - tcx, it.span, i_ty.ty, fty, + tcx, none, it.span, i_ty.ty, fty, {|| #fmt["intrinsic has wrong type. \ expected %s", ty_to_str(ccx.tcx, fty)]}); diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs index bb9bc0a6653..7a1eca4fc25 100644 --- a/src/rustc/middle/typeck/check/alt.rs +++ b/src/rustc/middle/typeck/check/alt.rs @@ -141,8 +141,8 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { fcx.infcx.resolve_type_vars_if_possible(fcx.expr_ty(end)); #debug["pat_range beginning type: %?", b_ty]; #debug["pat_range ending type: %?", e_ty]; - if !require_same_types_in_infcx( - fcx.infcx, pat.span, b_ty, e_ty, + if !require_same_types( + tcx, some(fcx.infcx), pat.span, b_ty, e_ty, {|| "mismatched types in range" }) { // no-op } else if !ty::type_is_numeric(b_ty) { diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index 4af075e8b79..1c2d1234118 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -154,6 +154,7 @@ class lookup { } fn add_candidates_from_param(n: uint, did: ast::def_id) { + #debug["candidates_from_param"]; let tcx = self.tcx(); let mut iface_bnd_idx = 0u; // count only iface bounds @@ -202,6 +203,8 @@ class lookup { fn add_candidates_from_iface(did: ast::def_id, iface_substs: ty::substs) { + #debug["method_from_iface"]; + let ms = *ty::iface_methods(self.tcx(), did); for ms.eachi {|i, m| if m.ident != self.m_name { cont; } @@ -235,6 +238,8 @@ class lookup { fn add_candidates_from_class(did: ast::def_id, class_substs: ty::substs) { + #debug["method_from_class"]; + let ms = *ty::iface_methods(self.tcx(), did); for ms.each {|m| @@ -285,6 +290,8 @@ class lookup { let impls_vecs = self.fcx.ccx.impl_map.get(self.expr.id); let mut added_any = false; + #debug["method_from_scope"]; + for list::each(impls_vecs) {|impls| for vec::each(*impls) {|im| // Check whether this impl has a method with the right name. @@ -297,9 +304,11 @@ class lookup { // if we can assign the caller to the callee, that's a // potential match. Collect those in the vector. - alt self.fcx.can_mk_assignty( + let can_assign = self.fcx.can_mk_assignty( self.self_expr, self.borrow_scope, - self.self_ty, impl_ty) { + self.self_ty, impl_ty); + #debug["can_assign = %?", can_assign]; + alt can_assign { result::err(_) { /* keep looking */ } result::ok(_) { let fty = self.ty_from_did(m.did); diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index 490656eccbe..b693ddb8492 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -25,8 +25,8 @@ import rscope::*; fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) { - // FIXME: hooking into the "intrinsic" root module is crude. - // there ought to be a better approach. Attributes? (#2592) + // FIXME (#2592): hooking into the "intrinsic" root module is crude. + // There ought to be a better approach. Attributes? for crate.node.module.items.each {|crate_item| if *crate_item.ident == "intrinsic" { @@ -210,7 +210,7 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span, ty::subst(tcx, substs, if_fty) }; require_same_types( - tcx, sp, impl_fty, if_fty, + tcx, none, sp, impl_fty, if_fty, {|| "method `" + *if_m.ident + "` has an incompatible type"}); ret; diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs index b188f990a68..e948e999e5c 100644 --- a/src/rustc/middle/typeck/infer.rs +++ b/src/rustc/middle/typeck/infer.rs @@ -193,13 +193,11 @@ export resolve_deep; export resolve_deep_var; export methods; // for infer_ctxt export unify_methods; // for infer_ctxt -export compare_tys; -export compare_tys_in_infcx; export fixup_err, fixup_err_to_str; export assignment; export root, to_str; export int_ty_set_all; -export force_level, force_none, force_non_region_vars_only, force_all; +export force_level, force_none, force_ty_vars_only, force_all; // Bitvector to represent sets of integral types enum int_ty_set = uint; @@ -389,25 +387,16 @@ fn can_mk_assignty(cx: infer_ctxt, anmnt: assignment, #debug["can_mk_assignty(%? / %s <: %s)", anmnt, a.to_str(cx), b.to_str(cx)]; - // FIXME---this will not unroll any entries we make in the - // borrowings table. But this is OK for the moment because this - // is only used in method lookup, and there must be exactly one - // match or an error is reported. Still, it should be fixed. (#2593) + // FIXME (#2593): this will not unroll any entries we make in the + // borrowings table. But this is OK for the moment because this is only + // used in method lookup, and there must be exactly one match or an + // error is reported. Still, it should be fixed. indent {|| cx.probe {|| cx.assign_tys(anmnt, a, b) } }.to_ures() } -fn compare_tys(tcx: ty::ctxt, a: ty::t, b: ty::t) -> ures { - let infcx = new_infer_ctxt(tcx); - mk_eqty(infcx, a, b) -} - -fn compare_tys_in_infcx(infcx: infer_ctxt, a: ty::t, b: ty::t) -> ures { - mk_eqty(infcx, a, b) -} - // See comment on the type `resolve_state` below fn resolve_shallow(cx: infer_ctxt, a: ty::t, force_vars: force_level) -> fres { @@ -1104,9 +1093,9 @@ enum force_level { // Any unconstrained variables are OK. force_none, - // Unconstrained region vars are OK; unconstrained ty vars and - // integral ty vars result in an error. - force_non_region_vars_only, + // Unconstrained region vars and integral ty vars are OK; + // unconstrained general-purpose ty vars result in an error. + force_ty_vars_only, // Any unconstrained variables result in an error. force_all, @@ -1248,7 +1237,7 @@ impl methods for resolve_state { { ub:_, lb:some(t) } { self.resolve1(t) } { ub:none, lb:none } { alt self.force_vars { - force_non_region_vars_only | force_all { + force_ty_vars_only | force_all { self.err = some(unresolved_ty(vid)); } force_none { /* ok */ } @@ -1271,7 +1260,7 @@ impl methods for resolve_state { some(t) { t } none { alt self.force_vars { - force_non_region_vars_only | force_all { + force_all { // As a last resort, default to int. let ty = ty::mk_int(self.infcx.tcx); self.infcx.set( @@ -1281,7 +1270,7 @@ impl methods for resolve_state { nde.rank)); ty } - force_none { + force_none | force_ty_vars_only { ty::mk_var_integral(self.infcx.tcx, vid) } } @@ -1718,16 +1707,16 @@ fn super_fns( argvecs(self, a_f.inputs, b_f.inputs).chain {|inputs| self.tys(a_f.output, b_f.output).chain {|output| self.purities(a_f.purity, b_f.purity).chain {|purity| - //FIXME self.infcx().constrvecs(a_f.constraints, - //FIXME b_f.constraints).then {|| - // (Fix this if #2588 doesn't get accepted) + // FIXME: uncomment if #2588 doesn't get accepted: + // self.infcx().constrvecs(a_f.constraints, + // b_f.constraints).then {|| ok({purity: purity, proto: p, inputs: inputs, output: output, ret_style: rs, constraints: a_f.constraints}) - //FIXME } + // } } } } diff --git a/src/rustc/util/common.rs b/src/rustc/util/common.rs index e12aa98b67a..6e6c5fa740e 100644 --- a/src/rustc/util/common.rs +++ b/src/rustc/util/common.rs @@ -70,8 +70,8 @@ fn local_rhs_span(l: @ast::local, def: span) -> span { } fn is_main_name(path: syntax::ast_map::path) -> bool { - // FIXME: path should be a constrained type, so we know - // the call to last doesn't fail (#34) + // FIXME (#34): path should be a constrained type, so we know + // the call to last doesn't fail. vec::last(path) == syntax::ast_map::path_name(@"main") } diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs index 431eb8b0aea..83167597bb8 100644 --- a/src/rustc/util/ppaux.rs +++ b/src/rustc/util/ppaux.rs @@ -28,12 +28,12 @@ fn bound_region_to_str(cx: ctxt, br: bound_region) -> str { } fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> str { - alt cx.items.get(node_id) { - ast_map::node_block(blk) { + alt cx.items.find(node_id) { + some(ast_map::node_block(blk)) { #fmt("", codemap::span_to_str(blk.span, cx.sess.codemap)) } - ast_map::node_expr(expr) { + some(ast_map::node_expr(expr)) { alt expr.node { ast::expr_call(*) { #fmt("", diff --git a/src/rustdoc/demo.rs b/src/rustdoc/demo.rs index dff9bfbc257..f39fe1f8120 100644 --- a/src/rustdoc/demo.rs +++ b/src/rustdoc/demo.rs @@ -8,7 +8,7 @@ for testing purposes. It doesn't surve any functional purpose. This here, for instance, is just some filler text. - FIXME (1654): It would be nice if we could run some automated + FIXME (#1654): It would be nice if we could run some automated tests on this file "]; diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs index 7f4c8aa6988..84d7c8c31fd 100644 --- a/src/rustdoc/doc.rs +++ b/src/rustdoc/doc.rs @@ -20,9 +20,9 @@ type section = { body: str }; -// FIXME: We currently give topmod the name of the crate. There would -// probably be fewer special cases if the crate had its own name and -// topmod's name was the empty string. (#2596) +// FIXME (#2596): We currently give topmod the name of the crate. There +// would probably be fewer special cases if the crate had its own name +// and topmod's name was the empty string. type cratedoc = { topmod: moddoc, }; diff --git a/src/snapshots.txt b/src/snapshots.txt index e2f0c151889..169a8667316 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2012-06-20 c891dec + macos-x86_64 cd7b3213a05e11dbf7440db016c9f7db16598501 + macos-i386 eba609b4c815c415ca9485cac749c08ede5bf9ff + freebsd-x86_64 c93d3297bf68d12a55af04fecab5c1792394fcca + linux-x86_64 eb0e614c6f463fdbf3f40953ff122eb7cd829b85 + linux-i386 6d858ef6915517135e633043115ab51d677010c5 + winnt-i386 ffc26150a21aac3c5b023070c0e52d3c01b1881c + S 2012-06-19 de491ea freebsd-x86_64 b5c1080df70136bb316286e1973fa2b5734c9a01 winnt-i386 fa1c7b2295dbde00269f859b8cb637a59a8deec4 diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs index af522ca8bc3..cde1c76e344 100644 --- a/src/test/bench/core-vec-append.rs +++ b/src/test/bench/core-vec-append.rs @@ -7,7 +7,7 @@ import io::writer_util; fn collect_raw(num: uint) -> [uint] { let mut result = []; for uint::range(0u, num) { |i| - result += [i]; + vec::push(result, i); } ret result; } @@ -43,18 +43,18 @@ fn main(args: [str]) { let raw = mid - start; let dvec = end - mid; - + let maxf = max as float; let rawf = raw as float; let dvecf = dvec as float; - + io::stdout().write_str(#fmt("Raw : %? seconds\n", raw)); io::stdout().write_str(#fmt(" : %f op/sec\n", maxf/rawf)); io::stdout().write_str(#fmt("\n")); io::stdout().write_str(#fmt("Dvec : %? seconds\n", dvec)); io::stdout().write_str(#fmt(" : %f op/sec\n", maxf/dvecf)); io::stdout().write_str(#fmt("\n")); - + if dvec < raw { io::stdout().write_str(#fmt("Dvec is %f%% faster than raw\n", (rawf - dvecf) / rawf * 100.0)); diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index e51cb6c98b2..6c6466017ef 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -1,6 +1,6 @@ /** -An implementation of the Graph500 Bread First Search problem in Rust. +An implementation of the Graph500 Breadth First Search problem in Rust. */ diff --git a/src/test/bench/msgsend-ring-new.rs b/src/test/bench/msgsend-ring-new.rs new file mode 100644 index 00000000000..cba62f2ada1 --- /dev/null +++ b/src/test/bench/msgsend-ring-new.rs @@ -0,0 +1,76 @@ +// This test creates a bunch of tasks that simultaneously send to each +// other in a ring. The messages should all be basically +// independent. It's designed to hammer the global kernel lock, so +// that things will look really good once we get that lock out of the +// message path. + +import newcomm::*; +import future::future; + +use std; +import std::time; + +fn thread_ring(i: uint, + count: uint, + num_chan: chan, + num_port: port) { + // Send/Receive lots of messages. + for uint::range(0u, count) {|j| + num_chan.send(i * j); + num_port.recv(); + }; +} + +fn main(args: [str]) { + let args = if os::getenv("RUST_BENCH").is_some() { + ["", "100", "10000"] + } else if args.len() <= 1u { + ["", "100", "1000"] + } else { + args + }; + + let num_tasks = option::get(uint::from_str(args[1])); + let msg_per_task = option::get(uint::from_str(args[2])); + + let num_port = port(); + let mut num_chan = chan(num_port); + + let start = time::precise_time_s(); + + // create the ring + let mut futures = []; + + for uint::range(1u, num_tasks) {|i| + let get_chan = port(); + let get_chan_chan = chan(get_chan); + { + let num_chan = num_chan.clone(); + futures += [future::spawn {|move num_chan, move get_chan_chan| + let p = port(); + get_chan_chan.send(chan(p)); + thread_ring(i, msg_per_task, num_chan, p) + }]; + } + + num_chan = get_chan.recv(); + }; + + // do our iteration + thread_ring(0u, msg_per_task, num_chan, num_port); + + // synchronize + for futures.each {|f| f.get() }; + + let stop = time::precise_time_s(); + + // all done, report stats. + let num_msgs = num_tasks * msg_per_task; + let elapsed = (stop - start); + let rate = (num_msgs as float) / elapsed; + + io::println(#fmt("Sent %? messages in %? seconds", + num_msgs, elapsed)); + io::println(#fmt(" %? messages / second", rate)); + io::println(#fmt(" %? μs / message", 1000000. / rate)); +} diff --git a/src/test/compile-fail/alt-pattern-field-mismatch-2.rs b/src/test/compile-fail/alt-pattern-field-mismatch-2.rs new file mode 100644 index 00000000000..75e0763e4a6 --- /dev/null +++ b/src/test/compile-fail/alt-pattern-field-mismatch-2.rs @@ -0,0 +1,16 @@ +fn main() { + enum color { + rgb(uint, uint, uint), + cmyk(uint, uint, uint, uint), + no_color, + } + + fn foo(c: color) { + alt c { + rgb(_, _, _) { } + cmyk(_, _, _, _) { } + no_color(_) { } + //!^ ERROR this pattern has 1 field, but the corresponding variant has no fields + } + } +} diff --git a/src/test/compile-fail/alt-pattern-field-mismatch.rs b/src/test/compile-fail/alt-pattern-field-mismatch.rs new file mode 100644 index 00000000000..086267a85b3 --- /dev/null +++ b/src/test/compile-fail/alt-pattern-field-mismatch.rs @@ -0,0 +1,16 @@ +fn main() { + enum color { + rgb(uint, uint, uint), + cmyk(uint, uint, uint, uint), + no_color, + } + + fn foo(c: color) { + alt c { + rgb(_, _) { } + //!^ ERROR this pattern has 2 fields, but the corresponding variant has 3 fields + cmyk(_, _, _, _) { } + no_color { } + } + } +} diff --git a/src/test/compile-fail/binop-logic-int.rs b/src/test/compile-fail/binop-logic-int.rs index ef8643bd7b4..ffa812c8b71 100644 --- a/src/test/compile-fail/binop-logic-int.rs +++ b/src/test/compile-fail/binop-logic-int.rs @@ -1,3 +1,3 @@ // error-pattern:&& cannot be applied to type `int` -fn main() { let x = 1 && 2; } +fn main() { let x = 1i && 2i; } diff --git a/src/test/compile-fail/borrowck-binding-mutbl.rs b/src/test/compile-fail/borrowck-binding-mutbl.rs new file mode 100644 index 00000000000..183106aa28e --- /dev/null +++ b/src/test/compile-fail/borrowck-binding-mutbl.rs @@ -0,0 +1,13 @@ +fn impure(_v: [int]) { +} + +fn main() { + let x = {mut f: [3]}; + + alt x { + {f: v} => { + impure(v); //! ERROR illegal borrow unless pure: unique value in aliasable, mutable location + //!^ NOTE impure due to access to impure function + } + } +} \ No newline at end of file diff --git a/src/test/compile-fail/borrowck-issue-2657-1.rs b/src/test/compile-fail/borrowck-issue-2657-1.rs new file mode 100644 index 00000000000..00c579dc45e --- /dev/null +++ b/src/test/compile-fail/borrowck-issue-2657-1.rs @@ -0,0 +1,9 @@ +fn main() { +let x = some(~1); +alt x { //! NOTE loan of immutable local variable granted here + some(y) { + let _a <- x; //! ERROR moving out of immutable local variable prohibited due to outstanding loan + } + _ {} +} +} diff --git a/src/test/compile-fail/borrowck-issue-2657-2.rs b/src/test/compile-fail/borrowck-issue-2657-2.rs new file mode 100644 index 00000000000..d8d068ee8fd --- /dev/null +++ b/src/test/compile-fail/borrowck-issue-2657-2.rs @@ -0,0 +1,9 @@ +fn main() { +let x = some(~1); +alt x { + some(y) { + let _b <- y; //! ERROR moving out of pattern binding + } + _ {} +} +} diff --git a/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs b/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs new file mode 100644 index 00000000000..03fbb6b975c --- /dev/null +++ b/src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs @@ -0,0 +1,7 @@ +fn foo(x: *~int) -> ~int { + let y <- *x; //! ERROR dereference of unsafe pointer requires unsafe function or block + ret y; +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/issue-1896.rs b/src/test/compile-fail/issue-1896.rs new file mode 100644 index 00000000000..eea82506061 --- /dev/null +++ b/src/test/compile-fail/issue-1896.rs @@ -0,0 +1,8 @@ +type t = { f: fn() -> T }; + +fn f(_x: t) {} + +fn main() { + let x: t<()> = { f: { || () } }; //! ERROR expressions with stack closure + f(x); +} diff --git a/src/test/compile-fail/issue-2111.rs b/src/test/compile-fail/issue-2111.rs new file mode 100644 index 00000000000..5e289af9f51 --- /dev/null +++ b/src/test/compile-fail/issue-2111.rs @@ -0,0 +1,11 @@ +fn foo(a: option, b: option) { + alt (a,b) { //! ERROR: non-exhaustive patterns: none not covered + (some(a), some(b)) if a == b { } + (some(_), none) | + (none, some(_)) { } + } +} + +fn main() { + foo(none, none); +} \ No newline at end of file diff --git a/src/test/compile-fail/issue-2467.rs b/src/test/compile-fail/issue-2467.rs new file mode 100644 index 00000000000..2429273e1ec --- /dev/null +++ b/src/test/compile-fail/issue-2467.rs @@ -0,0 +1,6 @@ +enum test { thing = 3u } //! ERROR mismatched types +//!^ ERROR expected signed integer constant +fn main() { + log(error, thing as int); + assert(thing as int == 3); +} diff --git a/src/test/compile-fail/issue-2590.rs b/src/test/compile-fail/issue-2590.rs new file mode 100644 index 00000000000..c27fee9f8a8 --- /dev/null +++ b/src/test/compile-fail/issue-2590.rs @@ -0,0 +1,13 @@ +import dvec::dvec; + +type parser = { + tokens: dvec, +}; + +impl parser for parser { + fn parse() -> [mut int] { + dvec::unwrap(self.tokens) //! ERROR illegal move from self + } +} + +fn main() {} diff --git a/src/test/compile-fail/vec-add.rs b/src/test/compile-fail/vec-add.rs index 2d96f0c6810..6d18bf9e2f8 100644 --- a/src/test/compile-fail/vec-add.rs +++ b/src/test/compile-fail/vec-add.rs @@ -1,3 +1,9 @@ +// xfail-test + +// FIXME: + should allow immutable or mutable vectors on the right +// hand side in all cases. We are getting compiler errors about this +// now, so I'm xfailing the test for now. -eholk + fn add(i: [int], m: [mut int], c: [const int]) { // Check that: @@ -6,23 +12,23 @@ fn add(i: [int], m: [mut int], c: [const int]) { add(i + [3], m + [3], - c + [3]); + [3]); add(i + [mut 3], m + [mut 3], - c + [mut 3]); + [mut 3]); add(i + i, m + i, - c + i); + i); add(i + m, m + m, - c + m); + m); add(i + c, m + c, - c + c); + c); add(m + [3], //! ERROR mismatched types m + [3], @@ -33,8 +39,10 @@ fn add(i: [int], m: [mut int], c: [const int]) { i + [3]); add(c + [3], //! ERROR mismatched types - c + [3], //! ERROR mismatched types - c + [3]); + //!^ ERROR binary operation + cannot be applied + c + [3], //! ERROR binary operation + cannot be applied + //!^ mismatched types + [3]); add(m + [mut 3], //! ERROR mismatched types m + [mut 3], @@ -44,9 +52,11 @@ fn add(i: [int], m: [mut int], c: [const int]) { i + [mut 3], //! ERROR mismatched types i + [mut 3]); - add(c + [mut 3], //! ERROR mismatched types - c + [mut 3], //! ERROR mismatched types - c + [mut 3]); + add(c + [mut 3], //! ERROR binary operation + cannot be applied + //!^ mismatched types + c + [mut 3], //! ERROR binary operation + cannot be applied + //!^ mismatched types + [mut 3]); add(m + i, //! ERROR mismatched types m + i, @@ -56,9 +66,11 @@ fn add(i: [int], m: [mut int], c: [const int]) { i + i, //! ERROR mismatched types i + i); - add(c + i, //! ERROR mismatched types - c + i, //! ERROR mismatched types - c + i); + add(c + i, //! ERROR binary operation + cannot be applied + //!^ ERROR mismatched types + c + i, //! ERROR binary operation + cannot be applied + //!^ ERROR mismatched types + i); add(m + m, //! ERROR mismatched types m + m, @@ -68,9 +80,11 @@ fn add(i: [int], m: [mut int], c: [const int]) { i + m, //! ERROR mismatched types i + m); - add(c + m, //! ERROR mismatched types - c + m, //! ERROR mismatched types - c + m); + add(c + m, //! ERROR binary operation + cannot be applied + //!^ ERROR mismatched types + c + m, //! ERROR binary operation + cannot be applied + //!^ ERROR mismatched types + m); add(m + c, //! ERROR mismatched types m + c, @@ -80,9 +94,11 @@ fn add(i: [int], m: [mut int], c: [const int]) { i + c, //! ERROR mismatched types i + c); - add(c + c, //! ERROR mismatched types - c + c, //! ERROR mismatched types - c + c); + add(c + c, //! ERROR binary operation + cannot be applied + //!^ ERROR mismatched types + c + c, //! ERROR binary operation + cannot be applied + //!^ ERROR mismatched types + c); } fn main() { diff --git a/src/test/run-fail/zip-different-lengths.rs b/src/test/run-fail/zip-different-lengths.rs index 4a5ac59efd2..736b61cb935 100644 --- a/src/test/run-fail/zip-different-lengths.rs +++ b/src/test/run-fail/zip-different-lengths.rs @@ -10,7 +10,7 @@ fn enum_chars(start: u8, end: u8) -> [char] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i as char]; i += 1u as u8; } + while i <= end { vec::push(r, i as char); i += 1u as u8; } ret r; } @@ -18,7 +18,7 @@ fn enum_uints(start: uint, end: uint) -> [uint] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i]; i += 1u; } + while i <= end { vec::push(r, i); i += 1u; } ret r; } diff --git a/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs b/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs new file mode 100644 index 00000000000..ef0803c00d0 --- /dev/null +++ b/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs @@ -0,0 +1,11 @@ +// just make sure this compiles: + +fn bar(x: *~int) -> ~int { + unsafe { + let y <- *x; + ret y; + } +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs index 50e7257a6a0..c1473b1a0d4 100644 --- a/src/test/run-pass/import-glob-crate.rs +++ b/src/test/run-pass/import-glob-crate.rs @@ -4,6 +4,6 @@ import vec::*; fn main() { let mut v = from_elem(0u, 0); - v += [4, 2]; + v = vec::append(v, [4, 2]); assert (reversed(v) == [2, 4]); } diff --git a/src/test/run-pass/issue-2101.rs b/src/test/run-pass/issue-2101.rs new file mode 100644 index 00000000000..35434e11f61 --- /dev/null +++ b/src/test/run-pass/issue-2101.rs @@ -0,0 +1,20 @@ +// xfail-test +use std; +import std::arena; +import std::arena::arena; + +enum hold { s(str) } + +fn init(ar: &a.arena::arena, str: str) -> &a.hold { + new(*ar) s(str) +} + +fn main(args: [str]) { + let ar = arena::arena(); + let leak = init(&ar, args[0]); + alt *leak { + s(astr) { + io::println(#fmt("%?", astr)); + } + }; +} diff --git a/src/test/run-pass/issue-2214.rs b/src/test/run-pass/issue-2214.rs new file mode 100644 index 00000000000..6795375e869 --- /dev/null +++ b/src/test/run-pass/issue-2214.rs @@ -0,0 +1,24 @@ +import libc::{c_double, c_int}; +import f64::*; + +fn lgamma(n: c_double, value: &mut int) -> c_double { + ret m::lgamma(n, value as &mut c_int); +} + +#[link_name = "m"] +#[abi = "cdecl"] +native mod m { + #[cfg(unix)] + #[link_name="lgamma_r"] fn lgamma(n: c_double, sign: &mut c_int) + -> c_double; + #[cfg(windows)] + #[link_name="__lgamma_r"] fn lgamma(n: c_double, + sign: &mut c_int) -> c_double; + +} + +fn main() { + let mut y: int = 5; + let x: &mut int = &mut y; + assert (lgamma(1.0 as c_double, x) == 0.0 as c_double); +} \ No newline at end of file diff --git a/src/test/run-pass/issue-912.rs b/src/test/run-pass/issue-912.rs new file mode 100644 index 00000000000..77a349b4ec9 --- /dev/null +++ b/src/test/run-pass/issue-912.rs @@ -0,0 +1,8 @@ +// xfail-test +fn find(_f: fn(@T) -> bool, _v: [@T]) {} + +fn main() { + let x = 10, arr = []; + find({|f| f.id == x}, arr); + arr += [{id: 20}]; // This assigns a type to arr +} diff --git a/src/test/run-pass/nested-class.rs b/src/test/run-pass/nested-class.rs new file mode 100644 index 00000000000..b0f62cc3ea9 --- /dev/null +++ b/src/test/run-pass/nested-class.rs @@ -0,0 +1,15 @@ +fn main() { + + class b { + let i: int; + fn do_stuff() -> int { ret 37; } + new(i:int) { self.i = i; } + } + + // fn b(x:int) -> int { fail; } + + let z = b(42); + assert(z.i == 42); + assert(z.do_stuff() == 37); + +} \ No newline at end of file diff --git a/src/test/run-pass/operator-overloading-leaks.rs b/src/test/run-pass/operator-overloading-leaks.rs new file mode 100644 index 00000000000..a67bffa2e92 --- /dev/null +++ b/src/test/run-pass/operator-overloading-leaks.rs @@ -0,0 +1,74 @@ +// The cases commented as "Leaks" need to not leak. Issue #2581 + +impl methods for [T] { + fn -(x: [T]/&) -> [T] { + [x[0], x[0], x[0]] + } + + fn foo(x: [T]/&) -> [T] { + [x[0], x[0], x[0]] + } +} + +impl methods for ~T { + fn +(rhs: ~T) -> ~T { + rhs + } +} + +impl methods for ~int { + fn -(rhs: ~int) -> ~int { + ~(*self - *rhs) + } +} + +impl methods for @int { + fn +(rhs: @int) -> @int { + @(*self + *rhs) + } +} + +fn main() { + // leaks + let mut bar = [1, 2, 3]; + bar -= [3, 2, 1]; + bar -= [4, 5, 6]; + + io::println(#fmt("%?", bar)); + + // okay + let mut bar = [1, 2, 3]; + bar = bar.foo([3, 2, 1]); + bar = bar.foo([4, 5, 6]); + + io::println(#fmt("%?", bar)); + + // okay + let mut bar = [1, 2, 3]; + bar = bar - [3, 2, 1]; + bar = bar - [4, 5, 6]; + + io::println(#fmt("%?", bar)); + + // Leaks + let mut bar = ~1; + bar += ~2; + bar += ~3; + + io:: println(#fmt("%?", bar)); + + // Leaks + let mut bar = ~1; + bar -= ~2; + bar -= ~3; + + io:: println(#fmt("%?", bar)); + + // Leaks + let mut bar = @1; + bar += @2; + bar += @3; + + io:: println(#fmt("%?", bar)); + +} diff --git a/src/test/run-pass/unary-minus-suffix-inference.rs b/src/test/run-pass/unary-minus-suffix-inference.rs new file mode 100644 index 00000000000..ce052203d4d --- /dev/null +++ b/src/test/run-pass/unary-minus-suffix-inference.rs @@ -0,0 +1,43 @@ +fn main() { + let a = 1; + let a_neg: i8 = -a; + log(error, a_neg); + + let b = 1; + let b_neg: i16 = -b; + log(error, b_neg); + + let c = 1; + let c_neg: i32 = -c; + log(error, b_neg); + + let d = 1; + let d_neg: i64 = -d; + log(error, b_neg); + + let e = 1; + let e_neg: int = -e; + log(error, b_neg); + + // intentional overflows + + let f = 1; + let f_neg: u8 = -f; + log(error, f_neg); + + let g = 1; + let g_neg: u16 = -g; + log(error, g_neg); + + let h = 1; + let h_neg: u32 = -h; + log(error, h_neg); + + let i = 1; + let i_neg: u64 = -i; + log(error, i_neg); + + let j = 1; + let j_neg: uint = -j; + log(error, j_neg); +} diff --git a/src/test/run-pass/vec-push.rs b/src/test/run-pass/vec-push.rs index 56661e13a32..15b9239c44b 100644 --- a/src/test/run-pass/vec-push.rs +++ b/src/test/run-pass/vec-push.rs @@ -1,5 +1 @@ - - -fn push(&v: [const T], t: T) { v += [t]; } - -fn main() { let mut v = [1, 2, 3]; push(v, 1); } +fn main() { let mut v = [1, 2, 3]; vec::push(v, 1); } diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs index 73a0f66d382..9ffb564ace6 100644 --- a/src/test/run-pass/zip-same-length.rs +++ b/src/test/run-pass/zip-same-length.rs @@ -10,7 +10,7 @@ fn enum_chars(start: u8, end: u8) -> [char] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i as char]; i += 1u as u8; } + while i <= end { vec::push(r, i as char); i += 1u as u8; } ret r; } @@ -18,7 +18,7 @@ fn enum_uints(start: uint, end: uint) -> [uint] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i]; i += 1u; } + while i <= end { vec::push(r, i); i += 1u; } ret r; }