From 055158d05191000384b490399c104394cbc0c838 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 6 Jun 2012 11:39:00 -0700 Subject: [PATCH] Revert "Merge pull request #2516 from mozilla/incoming" due to failures This reverts commit adb717b5fa3500c50ced39266c76fc909808c189, reversing changes made to aabf84cdd81351cc63ebdc9e2427203621d19950. --- src/libcore/cmp.rs | 10 ---- src/libcore/core.rc | 2 - src/libcore/int-template.rs | 14 ------ src/libcore/uint-template.rs | 14 ------ src/libstd/sort.rs | 13 +++-- src/rustc/driver/driver.rs | 4 +- src/rustc/driver/rustc.rs | 3 +- src/rustc/metadata/decoder.rs | 2 +- src/rustc/middle/astencode.rs | 9 ++++ src/rustc/middle/liveness.rs | 61 ++++++++++++++++++++---- src/rustc/middle/trans/base.rs | 34 +++++++++++-- src/rustc/middle/tstate/auxiliary.rs | 5 +- src/rustc/middle/ty.rs | 6 +-- src/rustc/middle/typeck/astconv.rs | 3 +- src/rustc/middle/typeck/check.rs | 9 +--- src/rustc/util/ppaux.rs | 10 +--- src/test/compile-fail/issue-2509-a.rs | 9 ---- src/test/run-pass/conditional-compile.rs | 6 +-- 18 files changed, 116 insertions(+), 98 deletions(-) delete mode 100644 src/libcore/cmp.rs delete mode 100644 src/test/compile-fail/issue-2509-a.rs diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs deleted file mode 100644 index aea97cf1649..00000000000 --- a/src/libcore/cmp.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[doc="Interfaces used for comparison."] - -iface ord { - fn lt(&&other: self) -> bool; -} - -iface eq { - fn eq(&&other: self) -> bool; -} - diff --git a/src/libcore/core.rc b/src/libcore/core.rc index efcd424024a..6b4c7ad7d3c 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -44,7 +44,6 @@ export extfmt; export tuple; export to_str; export dvec, dvec_iter; -export cmp; // NDM seems to be necessary for resolve to work export option_iter; @@ -153,7 +152,6 @@ mod tuple; // Ubiquitous-utility-type modules -mod cmp; mod either; mod iter; mod logging; diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs index 4011ac1a18a..156724cb061 100644 --- a/src/libcore/int-template.rs +++ b/src/libcore/int-template.rs @@ -1,5 +1,4 @@ import T = inst::T; -import cmp::{eq, ord}; export min_value, max_value; export min, max; @@ -11,7 +10,6 @@ export compl; export abs; export parse_buf, from_str, to_str, to_str_bytes, str; -export ord, eq; const min_value: T = -1 as T << (inst::bits - 1 as T); const max_value: T = min_value - 1 as T; @@ -110,18 +108,6 @@ fn to_str_bytes(n: T, radix: uint, f: fn([u8]/&) -> U) -> U { #[doc = "Convert to a string"] fn str(i: T) -> str { ret to_str(i, 10u); } -impl ord of ord for T { - fn lt(&&other: T) -> bool { - ret self < other; - } -} - -impl eq of eq for T { - fn eq(&&other: T) -> bool { - ret self == other; - } -} - // FIXME: Has alignment issues on windows and 32-bit linux #[test] diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs index 7126fb3d007..a63d01e6e8e 100644 --- a/src/libcore/uint-template.rs +++ b/src/libcore/uint-template.rs @@ -1,5 +1,4 @@ import T = inst::T; -import cmp::{eq, ord}; export min_value, max_value; export min, max; @@ -11,7 +10,6 @@ export compl; export to_str, to_str_bytes; export from_str, from_str_radix, str, parse_buf; -export ord, eq; const min_value: T = 0 as T; const max_value: T = 0 as T - 1 as T; @@ -51,18 +49,6 @@ fn range(lo: T, hi: T, it: fn(T) -> bool) { max_value ^ i } -impl ord of ord for T { - fn lt(&&other: T) -> bool { - ret self < other; - } -} - -impl eq of eq for T { - fn eq(&&other: T) -> bool { - ret self == other; - } -} - #[doc = " Parse a buffer of bytes diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 76c71d7ed2a..7e16578fd9c 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -1,6 +1,5 @@ #[doc = "Sorting methods"]; import vec::len; -import int::{eq, ord}; export le; export merge_sort; @@ -142,6 +141,7 @@ fn qsort3(compare_func_lt: le, compare_func_eq: le, qsort3::(compare_func_lt, compare_func_eq, arr, i, right); } +// FIXME: This should take lt and eq types (#2348) #[doc = " Fancy quicksort. Sorts a mut vector in place. @@ -152,9 +152,10 @@ fn qsort3(compare_func_lt: le, compare_func_eq: le, This is an unstable sort. "] -fn quick_sort3(arr: [mut T]) { +fn quick_sort3(compare_func_lt: le, compare_func_eq: le, + arr: [mut T]) { if len::(arr) == 0u { ret; } - qsort3::({ |x, y| x.lt(y) }, { |x, y| x.eq(y) }, arr, 0, + qsort3::(compare_func_lt, compare_func_eq, arr, 0, (len::(arr) as int) - 1); } @@ -162,7 +163,11 @@ fn quick_sort3(arr: [mut T]) { mod test_qsort3 { fn check_sort(v1: [mut int], v2: [mut int]) { let len = vec::len::(v1); - quick_sort3::(v1); + fn lt(&&a: int, &&b: int) -> bool { ret a < b; } + fn equal(&&a: int, &&b: int) -> bool { ret a == b; } + let f1 = lt; + let f2 = equal; + quick_sort3::(f1, f2, v1); let mut i = 0u; while i < len { log(debug, v2[i]); diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index e769455376a..6d4f48595d2 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -194,7 +194,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, bind middle::check_loop::check_crate(ty_cx, crate)); time(time_passes, "alt checking", bind middle::check_alt::check_crate(ty_cx, crate)); - let last_use_map = + let (last_use_map, spill_map) = time(time_passes, "liveness checking", bind middle::liveness::check_crate(ty_cx, method_map, crate)); time(time_passes, "typestate checking", @@ -216,7 +216,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, let maps = {mutbl_map: mutbl_map, root_map: root_map, copy_map: copy_map, last_use_map: last_use_map, impl_map: impl_map, method_map: method_map, - vtable_map: vtable_map}; + vtable_map: vtable_map, spill_map: spill_map}; let (llmod, link_meta) = time(time_passes, "translation", diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs index 5e88df1de5e..db185215bea 100644 --- a/src/rustc/driver/rustc.rs +++ b/src/rustc/driver/rustc.rs @@ -15,8 +15,7 @@ import getopts::{opt_present}; import rustc::driver::driver::*; import syntax::codemap; -import syntax::diagnostic; -import rustc::driver::session; +import rustc::driver::{diagnostic, session}; import rustc::middle::lint; import io::reader_util; diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index 4df45033a77..644d519fc0f 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -7,6 +7,7 @@ import syntax::attr; import middle::ty; import syntax::ast_map; +import common::*; import tydecode::{parse_ty_data, parse_def_id, parse_bounds_data, parse_ident}; import syntax::print::pprust; @@ -14,7 +15,6 @@ import util::ppaux::ty_to_str; import ebml::deserializer; import syntax::diagnostic::span_handler; -import common::*; export class_dtor; export get_class_fields; diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 6ebf0ed9ec6..2fd59cb2166 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -57,6 +57,7 @@ impl_map: middle::resolve::impl_map, method_map: middle::typeck::method_map, vtable_map: middle::typeck::vtable_map, + spill_map: middle::liveness::spill_map }; type decode_ctxt = @{ @@ -838,6 +839,12 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, } } + option::iter(maps.spill_map.find(id)) {|_m| + ebml_w.tag(c::tag_table_spill) {|| + ebml_w.id(id); + } + } + option::iter(maps.last_use_map.find(id)) {|m| ebml_w.tag(c::tag_table_last_use) {|| ebml_w.id(id); @@ -946,6 +953,8 @@ fn decode_side_tables(xcx: extended_decode_ctxt, dcx.maps.mutbl_map.insert(id, ()); } else if tag == (c::tag_table_copy as uint) { dcx.maps.copy_map.insert(id, ()); + } else if tag == (c::tag_table_spill as uint) { + dcx.maps.spill_map.insert(id, ()); } else { let val_doc = entry_doc[c::tag_table_val]; let val_dsr = ebml::ebml_deserializer(val_doc); diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index 048823f4553..3f82e647ab6 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -57,6 +57,7 @@ export check_crate; export last_use_map; +export spill_map; // Maps from an expr id to a list of variable ids for which this expr // is the last use. Typically, the expr is a path and the node id is @@ -65,6 +66,13 @@ // list of closed over variables that can be moved into the closure. type last_use_map = hashmap>; +// A set of variable ids which must be spilled (stored on the stack). +// We add in any variables or arguments where: +// (1) the variables are moved; +// (2) the address of the variable/argument is taken; +// or (3) we find a last use (as they may be moved). +type spill_map = hashmap; + enum variable = uint; enum live_node = uint; @@ -77,7 +85,7 @@ enum live_node_kind { fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, - crate: @crate) -> last_use_map { + crate: @crate) -> (last_use_map, spill_map) { let visitor = visit::mk_vt(@{ visit_fn: visit_fn, visit_local: visit_local, @@ -86,11 +94,12 @@ fn check_crate(tcx: ty::ctxt, }); let last_use_map = int_hash(); + let spill_map = int_hash(); let initial_maps = @ir_maps(tcx, method_map, - last_use_map); + last_use_map, spill_map); visit::visit_crate(*crate, initial_maps, visitor); tcx.sess.abort_if_errors(); - ret last_use_map; + ret (last_use_map, spill_map); } impl of to_str::to_str for live_node { @@ -153,6 +162,7 @@ fn relevant_def(def: def) -> option { let tcx: ty::ctxt; let method_map: typeck::method_map; let last_use_map: last_use_map; + let spill_map: spill_map; let mut num_live_nodes: uint; let mut num_vars: uint; @@ -164,10 +174,11 @@ fn relevant_def(def: def) -> option { let mut lnks: [live_node_kind]; new(tcx: ty::ctxt, method_map: typeck::method_map, - last_use_map: last_use_map) { + last_use_map: last_use_map, spill_map: spill_map) { self.tcx = tcx; self.method_map = method_map; self.last_use_map = last_use_map; + self.spill_map = spill_map; self.num_live_nodes = 0u; self.num_vars = 0u; @@ -253,6 +264,17 @@ fn lnk(ln: live_node) -> live_node_kind { self.lnks[*ln] } + fn add_spill(var: variable) { + let vk = self.var_kinds[*var]; + alt vk { + vk_local(id, _) | vk_arg(id, _, by_val) { + #debug["adding spill for %?", vk]; + self.spill_map.insert(id, ()); + } + vk_arg(*) | vk_field(_) | vk_self | vk_implicit_ret {} + } + } + fn add_last_use(expr_id: node_id, var: variable) { let vk = self.var_kinds[*var]; #debug["Node %d is a last use of variable %?", expr_id, vk]; @@ -286,7 +308,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, // swap in a new set of IR maps for this function body: let fn_maps = @ir_maps(self.tcx, self.method_map, - self.last_use_map); + self.last_use_map, self.spill_map); #debug["creating fn_maps: %x", ptr::addr_of(*fn_maps) as uint]; @@ -1385,7 +1407,11 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) { vt.visit_expr(f, self, vt); vec::iter2(args, targs) { |arg_expr, arg_ty| alt ty::resolved_mode(self.tcx, arg_ty.mode) { - by_val | by_copy | by_ref | by_mutbl_ref{ + by_val | by_copy { + vt.visit_expr(arg_expr, self, vt); + } + by_ref | by_mutbl_ref { + self.spill_expr(arg_expr); vt.visit_expr(arg_expr, self, vt); } by_move { @@ -1395,6 +1421,10 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) { } } + expr_addr_of(_, arg_expr) { + self.spill_expr(arg_expr); + } + // no correctness conditions related to liveness expr_if_check(*) | expr_if(*) | expr_alt(*) | expr_while(*) | expr_loop(*) | @@ -1404,7 +1434,7 @@ fn check_expr(expr: @expr, &&self: @liveness, vt: vt<@liveness>) { expr_assert(*) | expr_check(*) | expr_copy(*) | expr_loop_body(*) | expr_cast(*) | expr_unary(*) | expr_fail(*) | expr_ret(*) | expr_break | expr_cont | expr_lit(_) | - expr_block(*) | expr_swap(*) | expr_mac(*) | expr_addr_of(*) { + expr_block(*) | expr_swap(*) | expr_mac(*) { visit::visit_expr(expr, self, vt); } } @@ -1471,7 +1501,10 @@ fn check_move_from_var(span: span, ln: live_node, var: variable) { ln.to_str(), var.to_str()]; alt (*self).live_on_exit(ln, var) { - none { } + none { + // update spill map to include this variable, as it is moved: + (*self.ir).add_spill(var); + } some(lnk) { self.report_illegal_move(span, lnk, var); } @@ -1483,10 +1516,20 @@ fn consider_last_use(expr: @expr, ln: live_node, var: variable) { some(_) {} none { (*self.ir).add_last_use(expr.id, var); + + // update spill map to include this variable, as it may be moved: + (*self.ir).add_spill(var); } } } + fn spill_expr(expr: @expr) { + alt (*self).variable_from_path(expr) { + some(var) {(*self.ir).add_spill(var)} + none {} + } + } + fn check_move_from_expr(expr: @expr, vt: vt<@liveness>) { #debug["check_move_from_expr(node %d: %s)", expr.id, expr_to_str(expr)]; @@ -1732,4 +1775,4 @@ fn warn_about_dead_assign(sp: span, ln: live_node, var: variable) { } } } - } + } \ No newline at end of file diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 76a1777ab01..1eef30a1782 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -3749,8 +3749,6 @@ fn lval_to_dps(bcx: block, e: @ast::expr, dest: dest) -> block { let ty = expr_ty(bcx, e); let lv = trans_lval(bcx, e); let last_use = (lv.kind == owned && last_use_map.contains_key(e.id)); - #debug["is last use (%s) = %b, %d", expr_to_str(e), last_use, - lv.kind as int]; lval_result_to_dps(lv, ty, last_use, dest) } @@ -4041,10 +4039,29 @@ fn init_local(bcx: block, local: @ast::local) -> block { let ty = node_id_type(bcx, local.node.id); let llptr = alt bcx.fcx.lllocals.find(local.node.id) { some(local_mem(v)) { v } - _ { bcx.tcx().sess.span_bug(local.span, + some(_) { bcx.tcx().sess.span_bug(local.span, "init_local: Someone forgot to document why it's\ safe to assume local.node.init must be local_mem!"); + } + // This is a local that is kept immediate + none { + let initexpr = alt local.node.init { + some({expr, _}) { expr } + none { bcx.tcx().sess.span_bug(local.span, + "init_local: late-initialized var appears to \ + be an immediate -- possibly init_local was called \ + without calling alloc_local"); } + }; + let mut {bcx, val, kind} = trans_temp_lval(bcx, initexpr); + if kind != temporary { + if kind == owned { val = Load(bcx, val); } + let rs = take_ty_immediate(bcx, val, ty); + bcx = rs.bcx; val = rs.val; + add_clean_temp(bcx, val, ty); } + bcx.fcx.lllocals.insert(local.node.pat.id, local_imm(val)); + ret bcx; + } }; let mut bcx = bcx; @@ -4324,6 +4341,17 @@ fn alloc_local(cx: block, local: @ast::local) -> block { ast::pat_ident(pth, none) { some(path_to_ident(pth)) } _ { none } }; + // Do not allocate space for locals that can be kept immediate. + let ccx = cx.ccx(); + if option::is_some(simple_name) && + !ccx.maps.mutbl_map.contains_key(local.node.pat.id) && + !ccx.maps.spill_map.contains_key(local.node.pat.id) && + ty::type_is_immediate(t) { + alt local.node.init { + some({op: ast::init_assign, _}) { ret cx; } + _ {} + } + } let val = alloc_ty(cx, t); if cx.sess().opts.debuginfo { option::iter(simple_name) {|name| diff --git a/src/rustc/middle/tstate/auxiliary.rs b/src/rustc/middle/tstate/auxiliary.rs index a41812f72a7..c34953ac33e 100644 --- a/src/rustc/middle/tstate/auxiliary.rs +++ b/src/rustc/middle/tstate/auxiliary.rs @@ -13,8 +13,9 @@ set_postcondition, ts_ann, clear_in_postcond, clear_in_poststate_}; +import tritv::*; +import bitvectors::promises_; import driver::session::session; -import tritv::{dont_care, tfalse, tritv_get, ttrue}; import syntax::print::pprust::{constr_args_to_str, lit_to_str}; @@ -810,7 +811,7 @@ fn copy_in_poststate_two(fcx: fn_ctxt, src_post: poststate, // dest def_id let insts = find_instances(fcx, subst, val); for insts.each {|p| - if bitvectors::promises_(p.from, src_post) { + if promises_(p.from, src_post) { set_in_poststate_(p.to, target_post); } } diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 73f601cf4b0..3b32bca1e5f 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -4,19 +4,19 @@ import driver::session; import session::session; import syntax::{ast, ast_map}; +import syntax::ast::*; import syntax::ast_util; import syntax::ast_util::{is_local, local_def, split_class_items, new_def_hash}; import syntax::codemap::span; import metadata::csearch; +import util::common::*; import util::ppaux::region_to_str; import util::ppaux::vstore_to_str; import util::ppaux::{ty_to_str, tys_to_str, ty_constr_to_str}; +import syntax::print::pprust::*; import middle::lint::{get_warning_level, vecs_not_implicitly_copyable, ignore}; -import syntax::ast::*; -import syntax::print::pprust::*; - export ty_vid, region_vid, vid; export br_hashmap; export is_instantiable; diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index 476ef9d3ba5..d8ce3d83a60 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -45,8 +45,7 @@ "]; import check::fn_ctxt; -import rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope}; -import rscope::{in_binding_rscope, region_scope, type_rscope}; +import rscope::*; iface ast_conv { fn tcx() -> ty::ctxt; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index b3f7c5a9388..2649dc6c675 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -71,8 +71,7 @@ import method::{methods}; // methods for method::lookup import middle::ty::tys_in_fn_ty; import regionmanip::{replace_bound_regions_in_fn_ty, region_of}; -import rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope}; -import rscope::{in_binding_rscope, region_scope, type_rscope}; +import rscope::*; type fn_ctxt = // var_bindings, locals and next_var_id are shared @@ -387,12 +386,6 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) { }; // typecheck the members for members.each {|m| check_class_member(class_ccx, class_t, m); } - // Check that there's at least one field - let (fields,_) = split_class_items(members); - if fields.len() < 1u { - ccx.tcx.sess.span_err(it.span, "A class must have at least one \ - field"); - } // Check that the class is instantiable check_instantiable(ccx.tcx, it.span, it.id); } diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs index c5c445702d5..60f4ea8dabf 100644 --- a/src/rustc/util/ppaux.rs +++ b/src/rustc/util/ppaux.rs @@ -1,14 +1,6 @@ import std::map::hashmap; import middle::ty; -import middle::ty::{arg, bound_region, br_anon, br_named, canon_mode}; -import middle::ty::{ck_block, ck_box, ck_uniq, constr, ctxt, field, method}; -import middle::ty::{mt, re_bound, re_free, re_scope, re_var, region, t}; -import middle::ty::{ty_bool, ty_bot, ty_box, ty_class, ty_constr, ty_enum}; -import middle::ty::{ty_estr, ty_evec, ty_float, ty_fn, ty_iface, ty_int}; -import middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param}; -import middle::ty::{ty_ptr, ty_rec, ty_res, ty_rptr, ty_self, ty_str, ty_tup}; -import middle::ty::{ty_type, ty_uniq, ty_uint, ty_var, ty_var_integral}; -import middle::ty::{ty_vec, vid}; +import middle::ty::*; import metadata::encoder; import syntax::codemap; import syntax::print::pprust; diff --git a/src/test/compile-fail/issue-2509-a.rs b/src/test/compile-fail/issue-2509-a.rs deleted file mode 100644 index a500d249c07..00000000000 --- a/src/test/compile-fail/issue-2509-a.rs +++ /dev/null @@ -1,9 +0,0 @@ -class c { //! ERROR A class must have at least one field - new() { } -} - -fn main() { - let a = c(); - let x = [a]; - let _y = x[0]; -} diff --git a/src/test/run-pass/conditional-compile.rs b/src/test/run-pass/conditional-compile.rs index 2b64840d830..8f4bd22f75d 100644 --- a/src/test/run-pass/conditional-compile.rs +++ b/src/test/run-pass/conditional-compile.rs @@ -26,13 +26,11 @@ enum tg { bar, } #[cfg(bogus)] class r { - let i: int; - new(i:int) { self.i = i; } + new(i:int) {} } class r { - let i: int; - new(i:int) { self.i = i; } + new(i:int) {} } #[cfg(bogus)] -- GitLab