From 728496929292c692aaad005bdbf4376bb1d78c4f Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 21 Aug 2012 17:22:45 -0700 Subject: [PATCH] Eliminate many match checks in rustc --- src/fuzzer/fuzzer.rs | 16 +++++-------- src/libsyntax/parse/classify.rs | 4 ++-- src/rustc/back/link.rs | 18 +++++++-------- src/rustc/driver/driver.rs | 16 ++++++------- src/rustc/driver/session.rs | 16 +++++++++++-- src/rustc/middle/astencode.rs | 10 ++++---- src/rustc/middle/freevars.rs | 2 +- src/rustc/middle/kind.rs | 4 ++-- src/rustc/middle/lint.rs | 21 +++-------------- src/rustc/middle/trans/closure.rs | 2 +- src/rustc/middle/trans/consts.rs | 4 +++- src/rustc/middle/trans/debuginfo.rs | 36 +++++------------------------ 12 files changed, 61 insertions(+), 88 deletions(-) diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 6ceb788ac4c..9560faa0f0a 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -68,19 +68,15 @@ pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool { // If the fuzzer moves a block-ending-in-semicolon into callee // position, the pretty-printer can't preserve this even by // parenthesizing!! See email to marijn. - ast::expr_if(_, _, _) => { false } - ast::expr_block(_) => { false } - ast::expr_match(_, _, _) => { false } - ast::expr_while(_, _) => { false } + ast::expr_if(*) | ast::expr_block(*) + | ast::expr_match(*) | ast::expr_while(*) => { false } // https://github.com/mozilla/rust/issues/929 - ast::expr_cast(_, _) => { false } - ast::expr_assert(_) => { false } - ast::expr_binary(_, _, _) => { false } - ast::expr_assign(_, _) => { false } - ast::expr_assign_op(_, _, _) => { false } + ast::expr_cast(*) | ast::expr_assert(*) | + ast::expr_binary(*) | ast::expr_assign(*) | + ast::expr_assign_op(*) => { false } - ast::expr_fail(option::none) => { false } + ast::expr_fail(option::none) | ast::expr_ret(option::none) => { false } // https://github.com/mozilla/rust/issues/953 diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 1fd9dc2c23c..4082f223e4a 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -6,8 +6,8 @@ import ast_util::operator_prec; fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { match e.node { - ast::expr_if(_, _, _) | ast::expr_match(_, _, _) | ast::expr_block(_) - | ast::expr_while(_, _) | ast::expr_loop(_, _) + ast::expr_if(*) | ast::expr_match(*) | ast::expr_block(_) + | ast::expr_while(*) | ast::expr_loop(*) | ast::expr_call(_, _, true) => false, _ => true } diff --git a/src/rustc/back/link.rs b/src/rustc/back/link.rs index 8ac75916da0..dd0648666cc 100644 --- a/src/rustc/back/link.rs +++ b/src/rustc/back/link.rs @@ -84,7 +84,7 @@ mod write { if opts.save_temps { match opts.output_type { output_type_bitcode => { - if opts.optimize != 0u { + if opts.optimize != session::No { let filename = mk_intermediate_name(output, ~"no-opt.bc"); str::as_c_str(filename, |buf| { llvm::LLVMWriteBitcodeToFile(llmod, buf) @@ -107,7 +107,7 @@ mod write { // Also: Should we expose and use the pass lists used by the opt // tool? - if opts.optimize != 0u { + if opts.optimize != session::No { let fpm = mk_pass_manager(); llvm::LLVMAddTargetData(td.lltd, fpm.llpm); @@ -118,8 +118,8 @@ mod write { llvm::LLVMPassManagerBuilderDispose(FPMB); llvm::LLVMRunPassManager(fpm.llpm, llmod); - let mut threshold = 225u; - if opts.optimize == 3u { threshold = 275u; } + let mut threshold = 225; + if opts.optimize == session::Aggressive { threshold = 275; } let MPMB = llvm::LLVMPassManagerBuilderCreate(); llvm::LLVMPassManagerBuilderSetOptLevel(MPMB, @@ -146,11 +146,11 @@ mod write { let LLVMOptDefault = 2 as c_int; // -O2, -Os let LLVMOptAggressive = 3 as c_int; // -O3 - let mut CodeGenOptLevel = match check opts.optimize { - 0u => LLVMOptNone, - 1u => LLVMOptLess, - 2u => LLVMOptDefault, - 3u => LLVMOptAggressive + let mut CodeGenOptLevel = match opts.optimize { + session::No => LLVMOptNone, + session::Less => LLVMOptLess, + session::Default => LLVMOptDefault, + session::Aggressive => LLVMOptAggressive }; let mut FileType; diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index 36df337a4d4..106cce91ccb 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -1,6 +1,6 @@ // -*- rust -*- import metadata::{creader, cstore, filesearch}; -import session::{session, session_}; +import session::{session, session_, OptLevel, No, Less, Default, Aggressive}; import syntax::parse; import syntax::{ast, codemap}; import syntax::attr; @@ -488,24 +488,24 @@ fn build_session_options(matches: getopts::matches, link::output_type_llvm_assembly | link::output_type_assembly => (), _ => debugging_opts |= session::no_asm_comments } - let opt_level: uint = + let opt_level = if opt_present(matches, ~"O") { if opt_present(matches, ~"opt-level") { early_error(demitter, ~"-O and --opt-level both provided"); } - 2u + Default } else if opt_present(matches, ~"opt-level") { match getopts::opt_str(matches, ~"opt-level") { - ~"0" => 0u, - ~"1" => 1u, - ~"2" => 2u, - ~"3" => 3u, + ~"0" => No, + ~"1" => Less, + ~"2" => Default, + ~"3" => Aggressive, _ => { early_error(demitter, ~"optimization level needs " + ~"to be between 0-3") } } - } else { 0u }; + } else { No }; let target = match target_opt { none => host_triple(), diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index 172f940e2f1..5115fb4234a 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -70,12 +70,19 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ] } +enum OptLevel { + No, // -O0 + Less, // -O1 + Default, // -O2 + Aggressive // -O3 +} + type options = // The crate config requested for the session, which may be combined // with additional crate configurations during the compile process {crate_type: crate_type, static: bool, - optimize: uint, + optimize: OptLevel, debuginfo: bool, extra_debuginfo: bool, lint_opts: ~[(lint::lint, lint::level)], @@ -179,6 +186,11 @@ impl session { fn debugging_opt(opt: uint) -> bool { (self.opts.debugging_opts & opt) != 0u } + // This exists to help with refactoring to eliminate impossible + // cases later on + fn impossible_case(sp: span, msg: ~str) -> ! { + self.span_bug(sp, #fmt("Impossible case reached: %s", msg)); + } fn ppregions() -> bool { self.debugging_opt(ppregions) } fn time_passes() -> bool { self.debugging_opt(time_passes) } fn count_llvm_insns() -> bool { self.debugging_opt(count_llvm_insns) } @@ -199,7 +211,7 @@ fn basic_options() -> @options { @{ crate_type: session::lib_crate, static: false, - optimize: 0u, + optimize: No, debuginfo: false, extra_debuginfo: false, lint_opts: ~[], diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 3b1525c03f8..d8c5db4cd75 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -509,8 +509,8 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers { -> typeck::vtable_origin { do self.read_enum(~"vtable_origin") { do self.read_enum_variant |i| { - match check i { - 0u => { + match i { + 0 => { typeck::vtable_static( do self.read_enum_variant_arg(0u) { self.read_def_id(xcx) @@ -523,7 +523,7 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers { } ) } - 1u => { + 1 => { typeck::vtable_param( do self.read_enum_variant_arg(0u) { self.read_uint() @@ -533,7 +533,7 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers { } ) } - 2u => { + 2 => { typeck::vtable_trait( do self.read_enum_variant_arg(0u) { self.read_def_id(xcx) @@ -543,6 +543,8 @@ impl ebml::ebml_deserializer: vtable_deserialization_helpers { } ) } + // hard to avoid - user input + _ => fail ~"bad enum variant" } } } diff --git a/src/rustc/middle/freevars.rs b/src/rustc/middle/freevars.rs index 60489085bd9..e1760a7dde1 100644 --- a/src/rustc/middle/freevars.rs +++ b/src/rustc/middle/freevars.rs @@ -44,7 +44,7 @@ fn collect_freevars(def_map: resolve3::DefMap, blk: ast::blk) visit::visit_expr(expr, depth + 1, v); } } - ast::expr_fn_block(_, _, _) => { + ast::expr_fn_block(*) => { visit::visit_expr(expr, depth + 1, v); } ast::expr_path(path) => { diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index c7a5e7d64d4..e73cf84d947 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -191,7 +191,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span, // if this is the last use of the variable, then it will be // a move and not a copy let is_move = { - match check cx.last_use_map.find(fn_id) { + match cx.last_use_map.find(fn_id) { some(vars) => (*vars).contains(id), none => false } @@ -218,7 +218,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { // Handle any kind bounds on type parameters do option::iter(cx.tcx.node_type_substs.find(e.id)) |ts| { - let bounds = match check e.node { + let bounds = match e.node { expr_path(_) => { let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id)); ty::lookup_item_type(cx.tcx, did).bounds diff --git a/src/rustc/middle/lint.rs b/src/rustc/middle/lint.rs index cef94af4344..9105d811872 100644 --- a/src/rustc/middle/lint.rs +++ b/src/rustc/middle/lint.rs @@ -55,23 +55,6 @@ enum lint { non_camel_case_types } -// This is pretty unfortunate. We really want some sort of "deriving Enum" -// type of thing. -fn int_to_lint(i: int) -> lint { - match check i { - 0 => ctypes, - 1 => unused_imports, - 2 => while_true, - 3 => path_statement, - 4 => implicit_copies, - 5 => unrecognized_lint, - 6 => non_implicitly_copyable_typarams, - 7 => vecs_implicitly_copyable, - 8 => deprecated_mode, - 9 => non_camel_case_types - } -} - fn level_to_str(lv: level) -> ~str { match lv { allow => ~"allow", @@ -537,7 +520,7 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl, } let fn_ty = ty::node_id_to_type(tcx, id); - match check ty::get(fn_ty).struct { + match ty::get(fn_ty).struct { ty::ty_fn(fn_ty) => { let mut counter = 0; do vec::iter2(fn_ty.inputs, decl.inputs) |arg_ty, arg_ast| { @@ -572,6 +555,8 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl, } } } + _ => tcx.sess.impossible_case(span, ~"check_fn: function has \ + non-fn type") } } diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index 9e5bdc1964c..3304f0c4a54 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -272,7 +272,7 @@ fn build_closure(bcx0: block, vec::push(env_vals, env_ref(lv.val, ty, lv.kind)); } capture::cap_copy => { - let mv = match check ccx.maps.last_use_map.find(id) { + let mv = match ccx.maps.last_use_map.find(id) { none => false, some(vars) => (*vars).contains(nid) }; diff --git a/src/rustc/middle/trans/consts.rs b/src/rustc/middle/trans/consts.rs index 51b16fd19c8..4be8955541b 100644 --- a/src/rustc/middle/trans/consts.rs +++ b/src/rustc/middle/trans/consts.rs @@ -246,7 +246,7 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { let ety = ty::expr_ty(cx.tcx, e), llty = type_of::type_of(cx, ety); let basety = ty::expr_ty(cx.tcx, base); let v = const_expr(cx, base); - match check (base::cast_type_kind(basety), + match (base::cast_type_kind(basety), base::cast_type_kind(ety)) { (base::cast_integral, base::cast_integral) => { @@ -264,6 +264,8 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) } else { llvm::LLVMConstFPToUI(v, llty) } } + _ => cx.sess.impossible_case(e.span, + ~"bad combination of types for cast") } } ast::expr_addr_of(ast::m_imm, sub) => { diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index 325ce55d28f..68bdd983d8b 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -180,7 +180,7 @@ fn create_compile_unit(cx: @crate_ctxt) llstr(work_dir), llstr(env!{"CFG_VERSION"}), lli1(true), // deprecated: main compile unit - lli1(cx.sess.opts.optimize != 0u), + lli1(cx.sess.opts.optimize != session::No), llstr(~""), // flags (???) lli32(0) // runtime version (???) ]; @@ -281,7 +281,7 @@ fn size_and_align_of(cx: @crate_ctxt, t: ty::t) -> (int, int) { shape::llalign_of_pref(cx, llty) as int) } -fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: ast::prim_ty, span: span) +fn create_basic_type(cx: @crate_ctxt, t: ty::t, span: span) -> @metadata { let cache = get_cache(cx); let tg = BasicTypeDescriptorTag; @@ -291,29 +291,7 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: ast::prim_ty, span: span) option::none => () } - let (name, encoding) = match check ty { - ast::ty_bool => (~"bool", DW_ATE_boolean), - ast::ty_int(m) => match m { - ast::ty_char => (~"char", DW_ATE_unsigned), - ast::ty_i => (~"int", DW_ATE_signed), - ast::ty_i8 => (~"i8", DW_ATE_signed_char), - ast::ty_i16 => (~"i16", DW_ATE_signed), - ast::ty_i32 => (~"i32", DW_ATE_signed), - ast::ty_i64 => (~"i64", DW_ATE_signed) - }, - ast::ty_uint(m) => match m { - ast::ty_u => (~"uint", DW_ATE_unsigned), - ast::ty_u8 => (~"u8", DW_ATE_unsigned_char), - ast::ty_u16 => (~"u16", DW_ATE_unsigned), - ast::ty_u32 => (~"u32", DW_ATE_unsigned), - ast::ty_u64 => (~"u64", DW_ATE_unsigned) - }, - ast::ty_float(m) => match m { - ast::ty_f => (~"float", DW_ATE_float), - ast::ty_f32 => (~"f32", DW_ATE_float), - ast::ty_f64 => (~"f64", DW_ATE_float) - } - }; + let (name, encoding) = (~"uint", DW_ATE_unsigned); let fname = filename_from_span(cx, span); let file_node = create_file(cx, fname); @@ -443,8 +421,7 @@ fn create_boxed_type(cx: @crate_ctxt, outer: ty::t, _inner: ty::t, let file_node = create_file(cx, fname); //let cu_node = create_compile_unit_metadata(cx, fname); let uint_t = ty::mk_uint(cx.tcx); - let refcount_type = create_basic_type(cx, uint_t, - ast::ty_uint(ast::ty_u), span); + let refcount_type = create_basic_type(cx, uint_t, span); let scx = create_structure(file_node, ty_to_str(cx.tcx, outer), 0); add_member(scx, ~"refcnt", 0, sys::size_of::() as int, sys::min_align_of::() as int, refcount_type.node); @@ -495,8 +472,7 @@ fn create_vec(cx: @crate_ctxt, vec_t: ty::t, elem_t: ty::t, let file_node = create_file(cx, fname); let elem_ty_md = create_ty(cx, elem_t, elem_ty); let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t), 0); - let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx), - ast::ty_uint(ast::ty_u), vec_ty_span); + let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx), vec_ty_span); add_member(scx, ~"fill", 0, sys::size_of::() as int, sys::min_align_of::() as int, size_t_type.node); add_member(scx, ~"alloc", 0, sys::size_of::() as int, @@ -814,7 +790,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata { lli32(0i), //index into virt func /*llnull()*/ lli32(0), // base type with vtbl lli32(256), // flags - lli1(cx.sess.opts.optimize != 0u), + lli1(cx.sess.opts.optimize != session::No), fcx.llfn //list of template params //func decl descriptor