From abd29e5eadb46ec7d7126fa0438c1c52c4ace00f Mon Sep 17 00:00:00 2001 From: Zack Corr Date: Tue, 5 Feb 2013 22:56:40 +1000 Subject: [PATCH 01/14] core: Add a rand::Rand trait that is implemented by types that can be randomly generated Also adds Rng::gen() for generating any type that implements the Rand trait --- src/libcore/rand.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 976c186912b3..50232f99f85a 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -23,6 +23,102 @@ use uint; use util; use vec; +/// A type that can be randomly generated using an RNG +pub trait Rand { + static fn rand(rng: rand::Rng) -> Self; +} + +impl int: Rand { + static fn rand(rng: rand::Rng) -> int { + rng.gen_int() + } +} + +impl i8: Rand { + static fn rand(rng: rand::Rng) -> i8 { + rng.gen_i8() + } +} + +impl i16: Rand { + static fn rand(rng: rand::Rng) -> i16 { + rng.gen_i16() + } +} + +impl i32: Rand { + static fn rand(rng: rand::Rng) -> i32 { + rng.gen_i32() + } +} + +impl i64: Rand { + static fn rand(rng: rand::Rng) -> i64 { + rng.gen_i64() + } +} + +impl u8: Rand { + static fn rand(rng: rand::Rng) -> u8 { + rng.gen_u8() + } +} + +impl u16: Rand { + static fn rand(rng: rand::Rng) -> u16 { + rng.gen_u16() + } +} + +impl u32: Rand { + static fn rand(rng: rand::Rng) -> u32 { + rng.gen_u32() + } +} + +impl u64: Rand { + static fn rand(rng: rand::Rng) -> u64 { + rng.gen_u64() + } +} + +impl float: Rand { + static fn rand(rng: rand::Rng) -> float { + rng.gen_float() + } +} + +impl f32: Rand { + static fn rand(rng: rand::Rng) -> f32 { + rng.gen_f32() + } +} + +impl f64: Rand { + static fn rand(rng: rand::Rng) -> f64 { + rng.gen_f64() + } +} + +impl char: Rand { + static fn rand(rng: rand::Rng) -> char { + rng.gen_char() + } +} + +impl bool: Rand { + static fn rand(rng: rand::Rng) -> bool { + rng.gen_bool() + } +} + +impl Option: Rand { + static fn rand(rng: rand::Rng) -> Option { + if rng.gen_bool() { Some(Rand::rand(rng)) } + else { None } + } +} + #[allow(non_camel_case_types)] // runtime type enum rctx {} @@ -49,6 +145,10 @@ pub struct Weighted { /// Extension methods for random number generators impl Rng { + /// Return a random value for a Rand type + fn gen() -> T { + Rand::rand(self) + } /// Return a random int fn gen_int() -> int { From fd7b732e5873ff3085875f1de48b9d5c9721657c Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 5 Feb 2013 17:30:35 -0800 Subject: [PATCH 02/14] testsuite: Add test for #4523 --- src/test/compile-fail/issue-4523.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/compile-fail/issue-4523.rs diff --git a/src/test/compile-fail/issue-4523.rs b/src/test/compile-fail/issue-4523.rs new file mode 100644 index 000000000000..e72b73f8fa4c --- /dev/null +++ b/src/test/compile-fail/issue-4523.rs @@ -0,0 +1,17 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foopy() {} + +const f: fn() = foopy; //~ ERROR mismatched types: expected `&static/fn()` + +fn main () { + f(); +} \ No newline at end of file From 01cc9ecafeb235ad3c12aa2222c3911b2b450052 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Wed, 6 Feb 2013 16:49:24 +0900 Subject: [PATCH 03/14] libsyntax: no binary/hex float literals --- src/libsyntax/parse/lexer.rs | 7 +++++++ .../compile-fail/no-binary-float-literal.rs | 18 ++++++++++++++++++ src/test/compile-fail/no-hex-float-literal.rs | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 src/test/compile-fail/no-binary-float-literal.rs create mode 100644 src/test/compile-fail/no-hex-float-literal.rs diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 381183e736cf..0f672d1de81f 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -431,6 +431,13 @@ fn scan_number(c: char, rdr: string_reader) -> token::Token { let dec_part = scan_digits(rdr, 10u); num_str += ~"." + dec_part; } + if is_float { + match base { + 16u => rdr.fatal(~"hexadecimal float literal is not supported"), + 2u => rdr.fatal(~"binary float literal is not supported"), + _ => () + } + } match scan_exponent(rdr) { Some(ref s) => { is_float = true; diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/compile-fail/no-binary-float-literal.rs new file mode 100644 index 000000000000..58afd5ba349e --- /dev/null +++ b/src/test/compile-fail/no-binary-float-literal.rs @@ -0,0 +1,18 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern:binary float literal is not supported + +fn main() { + 0b101010f; + 0b101.010; + 0b101p4f; +} + diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/compile-fail/no-hex-float-literal.rs new file mode 100644 index 000000000000..3bc52e029d7c --- /dev/null +++ b/src/test/compile-fail/no-hex-float-literal.rs @@ -0,0 +1,18 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern:hexadecimal float literal is not supported + +fn main() { + 0xABC.Df; + 0x567.89; + 0xDEAD.BEEFp-2f; +} + From 2600bcc05dcd51a5f6fe3404c60a5c1891a22dfe Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Wed, 6 Feb 2013 17:43:14 +0900 Subject: [PATCH 04/14] got rid of last empty lines --- src/test/compile-fail/no-binary-float-literal.rs | 1 - src/test/compile-fail/no-hex-float-literal.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/compile-fail/no-binary-float-literal.rs index 58afd5ba349e..0fa61b1af52e 100644 --- a/src/test/compile-fail/no-binary-float-literal.rs +++ b/src/test/compile-fail/no-binary-float-literal.rs @@ -15,4 +15,3 @@ fn main() { 0b101.010; 0b101p4f; } - diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/compile-fail/no-hex-float-literal.rs index 3bc52e029d7c..4abb6093b244 100644 --- a/src/test/compile-fail/no-hex-float-literal.rs +++ b/src/test/compile-fail/no-hex-float-literal.rs @@ -15,4 +15,3 @@ fn main() { 0x567.89; 0xDEAD.BEEFp-2f; } - From 48df2f4aafec32f75141d57a99982643ce04ec85 Mon Sep 17 00:00:00 2001 From: kud1ing Date: Wed, 6 Feb 2013 10:14:50 +0100 Subject: [PATCH 05/14] `core::send_map` renamed to `core::hashmap` Encountered this while trying to port rustsqlite to rust 0.6 --- RELEASES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/RELEASES.txt b/RELEASES.txt index b3b81964d85a..64120f66351e 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -1,3 +1,9 @@ +Version 0.6 (?) +--------------------------- + + * Libraries + * `core::send_map` renamed to `core::hashmap` + Version 0.5 (December 2012) --------------------------- From 739e5ba369cfe19da10d7adf1bcfcd14b80f52bb Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 4 Feb 2013 15:30:32 -0800 Subject: [PATCH 06/14] rustc: Less copy --- src/librustc/middle/trans/base.rs | 26 +++++++++++++------------- src/librustc/middle/trans/common.rs | 4 +++- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a2b1de692beb..34a68c1468c5 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -137,7 +137,7 @@ pub fn log_fn_time(ccx: @crate_ctxt, +name: ~str, start: time::Timespec, ccx.stats.fn_times.push({ident: name, time: elapsed}); } -pub fn decl_fn(llmod: ModuleRef, name: ~str, cc: lib::llvm::CallConv, +pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, llty: TypeRef) -> ValueRef { let llfn: ValueRef = str::as_c_str(name, |buf| { unsafe { @@ -150,7 +150,7 @@ pub fn decl_fn(llmod: ModuleRef, name: ~str, cc: lib::llvm::CallConv, return llfn; } -pub fn decl_cdecl_fn(llmod: ModuleRef, +name: ~str, llty: TypeRef) +pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, llty: TypeRef) -> ValueRef { return decl_fn(llmod, name, lib::llvm::CCallConv, llty); } @@ -164,20 +164,19 @@ pub fn decl_internal_cdecl_fn(llmod: ModuleRef, +name: ~str, llty: TypeRef) -> return llfn; } -pub fn get_extern_fn(externs: HashMap<~str, ValueRef>, +pub fn get_extern_fn(externs: ExternMap, llmod: ModuleRef, - +name: ~str, + name: @str, cc: lib::llvm::CallConv, ty: TypeRef) -> ValueRef { if externs.contains_key_ref(&name) { return externs.get(&name); } - // XXX: Bad copy. - let f = decl_fn(llmod, copy name, cc, ty); + let f = decl_fn(llmod, name, cc, ty); externs.insert(name, f); return f; } -pub fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef, - +name: ~str, ty: TypeRef) -> ValueRef { +pub fn get_extern_const(externs: ExternMap, llmod: ModuleRef, + name: @str, ty: TypeRef) -> ValueRef { unsafe { if externs.contains_key_ref(&name) { return externs.get(&name); } let c = str::as_c_str(name, |buf| { @@ -189,9 +188,9 @@ pub fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef, } fn get_simple_extern_fn(cx: block, - externs: HashMap<~str, ValueRef>, + externs: ExternMap, llmod: ModuleRef, - +name: ~str, + name: @str, n_args: int) -> ValueRef { let _icx = cx.insn_ctxt("get_simple_extern_fn"); let ccx = cx.fcx.ccx; @@ -201,8 +200,8 @@ pub fn get_extern_const(externs: HashMap<~str, ValueRef>, llmod: ModuleRef, return get_extern_fn(externs, llmod, name, lib::llvm::CCallConv, t); } -pub fn trans_foreign_call(cx: block, externs: HashMap<~str, ValueRef>, - llmod: ModuleRef, +name: ~str, args: ~[ValueRef]) -> +pub fn trans_foreign_call(cx: block, externs: ExternMap, + llmod: ModuleRef, name: @str, args: ~[ValueRef]) -> ValueRef { let _icx = cx.insn_ctxt("trans_foreign_call"); let n = args.len() as int; @@ -474,6 +473,7 @@ pub fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, let class_ty = ty::subst_tps(tcx, substs, None, ty::lookup_item_type(tcx, parent_id).ty); let llty = type_of_dtor(ccx, class_ty); + let name = name.to_managed(); // :-( get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv, llty) } @@ -766,7 +766,7 @@ pub fn null_env_ptr(bcx: block) -> ValueRef { pub fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t) -> ValueRef { - let name = csearch::get_symbol(ccx.sess.cstore, did); + let name = csearch::get_symbol(ccx.sess.cstore, did).to_managed(); // Sad match ty::get(t).sty { ty::ty_fn(_) => { let llty = type_of_fn_from_ty(ccx, t); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 0613319e4afd..995d78a02e8e 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -152,13 +152,15 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res { } } +type ExternMap = HashMap<@str, ValueRef>; + // Crate context. Every crate we compile has one of these. pub struct crate_ctxt { sess: session::Session, llmod: ModuleRef, td: target_data, tn: type_names, - externs: HashMap<~str, ValueRef>, + externs: ExternMap, intrinsics: HashMap<~str, ValueRef>, item_vals: HashMap, exp_map2: resolve::ExportMap2, From b34f871ddac7bc84366b25c89d0a69926cb069e0 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 6 Feb 2013 14:28:02 -0800 Subject: [PATCH 07/14] librustc: Change i1 to i8 for bools. Attempts to put out burning tree. rs=burningtree --- src/librustc/middle/trans/_match.rs | 15 +++++++++-- src/librustc/middle/trans/base.rs | 25 ++++++++++++------ src/librustc/middle/trans/callee.rs | 7 ++++-- src/librustc/middle/trans/common.rs | 11 +++++++- src/librustc/middle/trans/controlflow.rs | 4 +++ src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc/middle/trans/expr.rs | 32 +++++++++++++++++------- src/librustc/middle/trans/foreign.rs | 23 +++++++++-------- src/librustc/middle/trans/reflect.rs | 1 + 9 files changed, 86 insertions(+), 34 deletions(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 7dca4174019c..99b5641ac6ad 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1028,6 +1028,8 @@ pub fn pick_col(m: &[@Match]) -> uint { pub enum branch_kind { no_branch, single, switch, compare, compare_vec_len, } // Compiles a comparison between two things. +// +// NB: This must produce an i1, not a Rust bool (i8). pub fn compare_values(cx: block, lhs: ValueRef, rhs: ValueRef, @@ -1053,7 +1055,11 @@ pub fn compare_values(cx: block, scratch_rhs], expr::SaveIn( scratch_result.val)); - return scratch_result.to_result(bcx); + let result = scratch_result.to_result(bcx); + Result { + bcx: result.bcx, + val: bool_to_i1(result.bcx, result.val) + } } ty::ty_estr(_) => { let scratch_result = scratch_datum(cx, ty::mk_bool(cx.tcx()), @@ -1063,7 +1069,11 @@ pub fn compare_values(cx: block, ~[lhs, rhs], expr::SaveIn( scratch_result.val)); - return scratch_result.to_result(bcx); + let result = scratch_result.to_result(bcx); + Result { + bcx: result.bcx, + val: bool_to_i1(result.bcx, result.val) + } } _ => { cx.tcx().sess.bug(~"only scalars and strings supported in \ @@ -1176,6 +1186,7 @@ pub fn compile_guard(bcx: block, expr::trans_to_datum(bcx, guard_expr).to_result() } }); + let val = bool_to_i1(bcx, val); // Revoke the temp cleanups now that the guard successfully executed. for temp_cleanups.each |llval| { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a2b1de692beb..b48eb088c504 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -494,8 +494,13 @@ pub fn maybe_name_value(cx: @crate_ctxt, v: ValueRef, s: ~str) { // Used only for creating scalar comparison glue. pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, } -pub fn compare_scalar_types(cx: block, lhs: ValueRef, rhs: ValueRef, - t: ty::t, op: ast::binop) -> Result { +// NB: This produces an i1, not a Rust bool (i8). +pub fn compare_scalar_types(cx: block, + lhs: ValueRef, + rhs: ValueRef, + t: ty::t, + op: ast::binop) + -> Result { let f = |a| compare_scalar_values(cx, lhs, rhs, a, op); match ty::get(t).sty { @@ -521,8 +526,12 @@ pub fn compare_scalar_types(cx: block, lhs: ValueRef, rhs: ValueRef, // A helper function to do the actual comparison of scalar values. -pub fn compare_scalar_values(cx: block, lhs: ValueRef, rhs: ValueRef, - nt: scalar_type, op: ast::binop) -> ValueRef { +pub fn compare_scalar_values(cx: block, + lhs: ValueRef, + rhs: ValueRef, + nt: scalar_type, + op: ast::binop) + -> ValueRef { let _icx = cx.insn_ctxt("compare_scalar_values"); fn die(cx: block) -> ! { cx.tcx().sess.bug(~"compare_scalar_values: must be a\ @@ -533,8 +542,8 @@ pub fn compare_scalar_values(cx: block, lhs: ValueRef, rhs: ValueRef, // We don't need to do actual comparisons for nil. // () == () holds but () < () does not. match op { - ast::eq | ast::le | ast::ge => return C_bool(true), - ast::ne | ast::lt | ast::gt => return C_bool(false), + ast::eq | ast::le | ast::ge => return C_i1(true), + ast::ne | ast::lt | ast::gt => return C_i1(false), // refinements would be nice _ => die(cx) } @@ -1442,7 +1451,7 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8())); let size = IntCast(cx, n_bytes, ccx.int_type); let align = C_i32(1i32); - let volatile = C_bool(false); + let volatile = C_i1(false); Call(cx, memcpy, ~[dst_ptr, src_ptr, size, align, volatile]); } @@ -1489,7 +1498,7 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { let llzeroval = C_u8(0); let size = IntCast(cx, machine::llsize_of(ccx, llty), ccx.int_type); let align = C_i32(1i32); - let volatile = C_bool(false); + let volatile = C_i1(false); Call(cx, llintrinsicfn, ~[llptr, llzeroval, size, align, volatile]); } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 8cfe8ba8f917..4bd5ae969f20 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -438,7 +438,9 @@ pub fn trans_call_inner( let flag = alloca(bcx, T_bool()); Store(bcx, C_bool(false), flag); Some(flag) - } else { None }; + } else { + None + }; let (llfn, llenv) = unsafe { match callee.data { @@ -506,7 +508,8 @@ pub fn trans_call_inner( if ty::type_is_bot(ret_ty) { Unreachable(bcx); } else if ret_in_loop { - bcx = do with_cond(bcx, Load(bcx, ret_flag.get())) |bcx| { + let ret_flag_result = bool_to_i1(bcx, Load(bcx, ret_flag.get())); + bcx = do with_cond(bcx, ret_flag_result) |bcx| { do option::iter(© bcx.fcx.loop_ret) |lret| { Store(bcx, C_bool(true), lret.flagptr); Store(bcx, C_bool(false), bcx.fcx.llretptr); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 0613319e4afd..837ca8ca3aad 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -759,7 +759,7 @@ pub fn T_f32() -> TypeRef { unsafe { return llvm::LLVMFloatType(); } } pub fn T_f64() -> TypeRef { unsafe { return llvm::LLVMDoubleType(); } } -pub fn T_bool() -> TypeRef { return T_i1(); } +pub fn T_bool() -> TypeRef { return T_i8(); } pub fn T_int(targ_cfg: @session::config) -> TypeRef { return match targ_cfg.arch { @@ -1109,6 +1109,10 @@ pub fn C_bool(b: bool) -> ValueRef { C_integral(T_bool(), if b { 1u64 } else { 0u64 }, False) } +pub fn C_i1(b: bool) -> ValueRef { + return C_integral(T_i1(), if b { 1 } else { 0 }, False); +} + pub fn C_i32(i: i32) -> ValueRef { return C_integral(T_i32(), i as u64, True); } @@ -1435,6 +1439,11 @@ pub fn struct_dtor() -> [uint * 2] { [0, 1] } +// Casts a Rust bool value to an i1. +pub fn bool_to_i1(bcx: block, llval: ValueRef) -> ValueRef { + build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false)) +} + // // Local Variables: // mode: rust diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 8944fceb0119..a1505dd2f11c 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -62,6 +62,8 @@ pub fn trans_if(bcx: block, let then_bcx_in = scope_block(bcx, thn.info(), ~"then"); let else_bcx_in = scope_block(bcx, els.info(), ~"else"); + + let cond_val = bool_to_i1(bcx, cond_val); CondBr(bcx, cond_val, then_bcx_in.llbb, else_bcx_in.llbb); debug!("then_bcx_in=%s, else_bcx_in=%s", @@ -139,6 +141,7 @@ pub fn trans_while(bcx: block, cond: @ast::expr, body: ast::blk) -> block { // compile the condition let Result {bcx: cond_bcx_out, val: cond_val} = expr::trans_to_datum(cond_bcx_in, cond).to_result(); + let cond_val = bool_to_i1(cond_bcx_out, cond_val); let cond_bcx_out = trans_block_cleanups(cond_bcx_out, block_cleanups(cond_bcx_in)); CondBr(cond_bcx_out, cond_val, body_bcx_in.llbb, next_bcx.llbb); @@ -324,6 +327,7 @@ pub fn trans_check_expr(bcx: block, expr::trans_to_datum(bcx, pred_expr).to_result() } }; + let val = bool_to_i1(bcx, val); do with_cond(bcx, Not(bcx, val)) |bcx| { trans_fail(bcx, Some(pred_expr.span), /*bad*/copy expr_str) } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ecb63c19811c..ff842b5b4bed 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -77,7 +77,7 @@ fn lli64(val: int) -> ValueRef { C_i64(val as i64) } fn lli1(bval: bool) -> ValueRef { - C_bool(bval) + C_i1(bval) } fn llmdnode(elems: ~[ValueRef]) -> ValueRef { unsafe { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index e19bafdb5984..61204fe4e07e 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1236,7 +1236,6 @@ fn trans_unary_datum(bcx: block, un_expr: @ast::expr, op: ast::unop, sub_expr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_unary_datum"); // if deref, would be LvalueExpr @@ -1251,7 +1250,21 @@ fn trans_unary_datum(bcx: block, return match op { ast::not => { let Result {bcx, val} = trans_to_datum(bcx, sub_expr).to_result(); - immediate_rvalue_bcx(bcx, Not(bcx, val), un_ty) + + // If this is a boolean type, we must not use the LLVM Not + // instruction, as that is a *bitwise* not and we want *logical* + // not on our 8-bit boolean values. + let llresult = match ty::get(un_ty).sty { + ty::ty_bool => { + let llcond = ICmp(bcx, + lib::llvm::IntEQ, + val, + C_bool(false)); + Select(bcx, llcond, C_bool(true), C_bool(false)) + } + _ => Not(bcx, val) + }; + immediate_rvalue_bcx(bcx, llresult, un_ty) } ast::neg => { let Result {bcx, val} = trans_to_datum(bcx, sub_expr).to_result(); @@ -1308,8 +1321,8 @@ fn trans_eager_binop(bcx: block, binop_ty: ty::t, op: ast::binop, lhs_datum: &Datum, - rhs_datum: &Datum) -> DatumBlock -{ + rhs_datum: &Datum) + -> DatumBlock { let mut bcx = bcx; let _icx = bcx.insn_ctxt("trans_eager_binop"); @@ -1388,7 +1401,7 @@ fn trans_eager_binop(bcx: block, } let cmpr = base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op); bcx = cmpr.bcx; - cmpr.val + ZExt(bcx, cmpr.val, T_i8()) } } _ => { @@ -1406,8 +1419,7 @@ fn trans_lazy_binop(bcx: block, binop_expr: @ast::expr, op: lazy_binop_ty, a: @ast::expr, - b: @ast::expr) -> DatumBlock -{ + b: @ast::expr) -> DatumBlock { let _icx = bcx.insn_ctxt("trans_lazy_binop"); let binop_ty = expr_ty(bcx, binop_expr); let mut bcx = bcx; @@ -1425,10 +1437,12 @@ fn trans_lazy_binop(bcx: block, let join = base::sub_block(bcx, ~"join"); let before_rhs = base::sub_block(bcx, ~"rhs"); + let lhs_i1 = bool_to_i1(past_lhs, lhs); match op { - lazy_and => CondBr(past_lhs, lhs, before_rhs.llbb, join.llbb), - lazy_or => CondBr(past_lhs, lhs, join.llbb, before_rhs.llbb) + lazy_and => CondBr(past_lhs, lhs_i1, before_rhs.llbb, join.llbb), + lazy_or => CondBr(past_lhs, lhs_i1, join.llbb, before_rhs.llbb) } + let Result {bcx: past_rhs, val: rhs} = { do base::with_scope_result(before_rhs, b.info(), ~"rhs") |bcx| { trans_to_datum(bcx, b).to_result() diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 171fdc79e3a7..ae05ceb1ec57 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -524,7 +524,8 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, } ~"needs_drop" => { let tp_ty = substs.tys[0]; - Store(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)), + Store(bcx, + C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)), fcx.llretptr); } ~"visit_tydesc" => { @@ -574,7 +575,7 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, let src_ptr = get_param(decl, first_real_arg + 1); let size = get_param(decl, first_real_arg + 2); let align = C_i32(1); - let volatile = C_bool(false); + let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get( &~"llvm.memmove.p0i8.p0i8.i32"); Call(bcx, llfn, ~[dst_ptr, src_ptr, size, align, volatile]); @@ -584,7 +585,7 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, let src_ptr = get_param(decl, first_real_arg + 1); let size = get_param(decl, first_real_arg + 2); let align = C_i32(1); - let volatile = C_bool(false); + let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get( &~"llvm.memmove.p0i8.p0i8.i64"); Call(bcx, llfn, ~[dst_ptr, src_ptr, size, align, volatile]); @@ -769,49 +770,49 @@ pub fn trans_intrinsic(ccx: @crate_ctxt, } ~"ctlz8" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let ctlz = ccx.intrinsics.get(&~"llvm.ctlz.i8"); Store(bcx, Call(bcx, ctlz, ~[x, y]), fcx.llretptr) } ~"ctlz16" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let ctlz = ccx.intrinsics.get(&~"llvm.ctlz.i16"); Store(bcx, Call(bcx, ctlz, ~[x, y]), fcx.llretptr) } ~"ctlz32" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let ctlz = ccx.intrinsics.get(&~"llvm.ctlz.i32"); Store(bcx, Call(bcx, ctlz, ~[x, y]), fcx.llretptr) } ~"ctlz64" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let ctlz = ccx.intrinsics.get(&~"llvm.ctlz.i64"); Store(bcx, Call(bcx, ctlz, ~[x, y]), fcx.llretptr) } ~"cttz8" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let cttz = ccx.intrinsics.get(&~"llvm.cttz.i8"); Store(bcx, Call(bcx, cttz, ~[x, y]), fcx.llretptr) } ~"cttz16" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let cttz = ccx.intrinsics.get(&~"llvm.cttz.i16"); Store(bcx, Call(bcx, cttz, ~[x, y]), fcx.llretptr) } ~"cttz32" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let cttz = ccx.intrinsics.get(&~"llvm.cttz.i32"); Store(bcx, Call(bcx, cttz, ~[x, y]), fcx.llretptr) } ~"cttz64" => { let x = get_param(decl, first_real_arg); - let y = C_bool(false); + let y = C_i1(false); let cttz = ccx.intrinsics.get(&~"llvm.cttz.i64"); Store(bcx, Call(bcx, cttz, ~[x, y]), fcx.llretptr) } diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 59ba55920fd5..7380fa2e5626 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -109,6 +109,7 @@ pub impl reflector { ast::m_imm)), ArgVals(args), SaveIn(scratch.val), DontAutorefArg); let result = scratch.to_value_llval(bcx); + let result = bool_to_i1(bcx, result); let next_bcx = sub_block(bcx, ~"next"); CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb); self.bcx = next_bcx From b91a51daca705b5aebfa58079963f24592a7e411 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 6 Feb 2013 00:03:12 -0500 Subject: [PATCH 08/14] remove issue #3148 workarounds (no longer needed) --- src/libcore/hashmap.rs | 7 ++----- src/libstd/json.rs | 8 -------- src/libstd/treemap.rs | 1 - 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index adb16a929055..88981f514cff 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -49,9 +49,8 @@ pub mod linear { buckets: ~[Option>], } - // FIXME(#3148) -- we could rewrite FoundEntry - // to have type Option<&Bucket> which would be nifty - // However, that won't work until #3148 is fixed + // We could rewrite FoundEntry to have type Option<&Bucket> + // which would be nifty enum SearchResult { FoundEntry(uint), FoundHole(uint), TableFull } @@ -296,8 +295,6 @@ pub mod linear { FoundEntry(idx) => { match self.buckets[idx] { Some(ref bkt) => { - // FIXME(#3148)---should be inferred - let bkt: &self/Bucket = bkt; Some(&bkt.value) } None => { diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 4b34f318e91b..13b58c433006 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -856,9 +856,6 @@ pub impl Decoder: serialize::Decoder { debug!("read_vec_elt(idx=%u)", idx); match *self.peek() { List(ref list) => { - // FIXME(#3148)---should be inferred - let list: &self/~[Json] = list; - self.stack.push(&list[idx]); f() } @@ -885,9 +882,6 @@ pub impl Decoder: serialize::Decoder { let top = self.peek(); match *top { Object(ref obj) => { - // FIXME(#3148) This hint should not be necessary. - let obj: &self/~Object = obj; - match obj.find(&name.to_owned()) { None => die!(fmt!("no such field: %s", name)), Some(json) => { @@ -917,8 +911,6 @@ pub impl Decoder: serialize::Decoder { debug!("read_tup_elt(idx=%u)", idx); match *self.peek() { List(ref list) => { - // FIXME(#3148)---should be inferred - let list: &self/~[Json] = list; self.stack.push(&list[idx]); f() } diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 1105d65a4ed6..b7af5de4cbfe 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -142,7 +142,6 @@ impl TreeMap: Map { loop { match *current { Some(ref r) => { - let r: &self/~TreeNode = r; // FIXME: #3148 if *key < r.key { current = &r.left; } else if r.key < *key { From 5b6c26b4e44e05717cc9a1d0041f44fb4df4d102 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 6 Feb 2013 02:10:53 -0500 Subject: [PATCH 09/14] treemap: get rid of some implicit vector copies --- src/libstd/treemap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index b7af5de4cbfe..87801d765054 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -745,8 +745,8 @@ mod test_treemap { let v1 = str::to_bytes(~"baz"); let v2 = str::to_bytes(~"foobar"); - m.insert(k1, v1); - m.insert(k2, v2); + m.insert(copy k1, copy v1); + m.insert(copy k2, copy v2); assert m.find(&k2) == Some(&v2); assert m.find(&k1) == Some(&v1); From 37e998696f840ffea047efc50814819422750c20 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 6 Feb 2013 02:27:33 -0500 Subject: [PATCH 10/14] get rid of implicit vec copies in treemap iterator Each call to next() was doing a copy rather than a move. There's currently no way for this to be a method that uses &mut self, so it has to be a free function. Closes #4763. --- src/libstd/treemap.rs | 136 +++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 87801d765054..610f2f5a59c2 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -49,8 +49,8 @@ impl TreeMap: Eq { let mut y = other.iter(); for self.len().times { unsafe { // unsafe as a purity workaround - x = x.next(); - y = y.next(); + map_next(&mut x); + map_next(&mut y); // FIXME: #4492 (ICE), x.get() == y.get() let (x1, x2) = x.get().unwrap(); let (y1, y2) = y.get().unwrap(); @@ -74,8 +74,8 @@ pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { let (a_len, b_len) = (a.len(), b.len()); for uint::min(a_len, b_len).times { unsafe { // purity workaround - x = x.next(); - y = y.next(); + map_next(&mut x); + map_next(&mut y); let (key_a,_) = x.get().unwrap(); let (key_b,_) = y.get().unwrap(); if *key_a < *key_b { return true; } @@ -210,32 +210,30 @@ impl TreeMapIterator { // Returns the current node, or None if this iterator is at the end. fn get(&const self) -> Option<(&self/K, &self/V)> { match self.current { - Some(res) => Some((&res.key, &res.value)), - None => None + Some(res) => Some((&res.key, &res.value)), + None => None } } +} - /// Advance the iterator to the next node (in order). If this iterator - /// is finished, does nothing. - fn next(self) -> TreeMapIterator/&self { - let mut this = self; - while !this.stack.is_empty() || this.node.is_some() { - match *this.node { - Some(ref x) => { - this.stack.push(x); - this.node = &x.left; - } - None => { - let res = this.stack.pop(); - this.node = &res.right; - this.current = Some(res); - return this; - } - } +/// Advance the iterator to the next node (in order). If this iterator +/// is finished, does nothing. +fn map_next(iter: &mut TreeMapIterator/&a) { + while !iter.stack.is_empty() || iter.node.is_some() { + match *iter.node { + Some(ref x) => { + iter.stack.push(x); + iter.node = &x.left; + } + None => { + let res = iter.stack.pop(); + iter.node = &res.right; + iter.current = Some(res); + return; + } } - this.current = None; - return this; } + iter.current = None; } pub struct TreeSet { @@ -297,18 +295,18 @@ impl TreeSet: Set { let mut x = self.iter(); let mut y = other.iter(); unsafe { // purity workaround - x = x.next(); - y = y.next(); + set_next(&mut x); + set_next(&mut y); let mut a = x.get(); let mut b = y.get(); while a.is_some() && b.is_some() { let a1 = a.unwrap(); let b1 = b.unwrap(); if a1 < b1 { - x = x.next(); + set_next(&mut x); a = x.get(); } else if b1 < a1 { - y = y.next(); + set_next(&mut y); b = y.get(); } else { return false; @@ -328,8 +326,8 @@ impl TreeSet: Set { let mut x = self.iter(); let mut y = other.iter(); unsafe { // purity workaround - x = x.next(); - y = y.next(); + set_next(&mut x); + set_next(&mut y); let mut a = x.get(); let mut b = y.get(); while b.is_some() { @@ -345,10 +343,10 @@ impl TreeSet: Set { } if !(a1 < b1) { - y = y.next(); + set_next(&mut y); b = y.get(); } - x = x.next(); + set_next(&mut x); a = x.get(); } } @@ -361,15 +359,15 @@ impl TreeSet: Set { let mut y = other.iter(); unsafe { // purity workaround - x = x.next(); - y = y.next(); + set_next(&mut x); + set_next(&mut y); let mut a = x.get(); let mut b = y.get(); while a.is_some() { if b.is_none() { return do a.while_some() |a1| { - if f(a1) { x = x.next(); x.get() } else { None } + if f(a1) { set_next(&mut x); x.get() } else { None } } } @@ -378,11 +376,11 @@ impl TreeSet: Set { if a1 < b1 { if !f(a1) { return } - x = x.next(); + set_next(&mut x); a = x.get(); } else { - if !(b1 < a1) { x = x.next(); a = x.get() } - y = y.next(); + if !(b1 < a1) { set_next(&mut x); a = x.get() } + set_next(&mut y); b = y.get(); } } @@ -396,15 +394,15 @@ impl TreeSet: Set { let mut y = other.iter(); unsafe { // purity workaround - x = x.next(); - y = y.next(); + set_next(&mut x); + set_next(&mut y); let mut a = x.get(); let mut b = y.get(); while a.is_some() { if b.is_none() { return do a.while_some() |a1| { - if f(a1) { x.next(); x.get() } else { None } + if f(a1) { set_next(&mut x); x.get() } else { None } } } @@ -413,21 +411,21 @@ impl TreeSet: Set { if a1 < b1 { if !f(a1) { return } - x = x.next(); + set_next(&mut x); a = x.get(); } else { if b1 < a1 { if !f(b1) { return } } else { - x = x.next(); + set_next(&mut x); a = x.get(); } - y = y.next(); + set_next(&mut y); b = y.get(); } } do b.while_some |b1| { - if f(b1) { y = y.next(); y.get() } else { None } + if f(b1) { set_next(&mut y); y.get() } else { None } } } } @@ -438,8 +436,8 @@ impl TreeSet: Set { let mut y = other.iter(); unsafe { // purity workaround - x = x.next(); - y = y.next(); + set_next(&mut x); + set_next(&mut y); let mut a = x.get(); let mut b = y.get(); @@ -447,13 +445,13 @@ impl TreeSet: Set { let a1 = a.unwrap(); let b1 = b.unwrap(); if a1 < b1 { - x = x.next(); + set_next(&mut x); a = x.get(); } else { if !(b1 < a1) { if !f(a1) { return } } - y = y.next(); + set_next(&mut y); b = y.get(); } } @@ -466,15 +464,15 @@ impl TreeSet: Set { let mut y = other.iter(); unsafe { // purity workaround - x = x.next(); - y = y.next(); + set_next(&mut x); + set_next(&mut y); let mut a = x.get(); let mut b = y.get(); while a.is_some() { if b.is_none() { return do a.while_some() |a1| { - if f(a1) { x = x.next(); x.get() } else { None } + if f(a1) { set_next(&mut x); x.get() } else { None } } } @@ -483,15 +481,15 @@ impl TreeSet: Set { if b1 < a1 { if !f(b1) { return } - y = y.next(); + set_next(&mut y); b = y.get(); } else { if !f(a1) { return } if !(a1 < b1) { - y = y.next(); + set_next(&mut y); b = y.get() } - x = x.next(); + set_next(&mut x); a = x.get(); } } @@ -524,16 +522,16 @@ impl TreeSetIterator { /// Returns the current node, or None if this iterator is at the end. fn get(&const self) -> Option<&self/T> { match self.iter.get() { - None => None, - Some((k, _)) => Some(k) + None => None, + Some((k, _)) => Some(k) } } +} - /// Advance the iterator to the next node (in order). If this iterator is - /// finished, does nothing. - fn next(self) -> TreeSetIterator/&self { - TreeSetIterator { iter: self.iter.next() } - } +/// Advance the iterator to the next node (in order). If this iterator is +/// finished, does nothing. +fn set_next(iter: &mut TreeSetIterator/&a) { + map_next(&mut iter.iter); } // Nodes keep track of their level in the tree, starting at 1 in the @@ -967,18 +965,18 @@ mod test_treemap { // FIXME: #4492 (ICE): iter.next() == Some((&x1, &y1)) - iter = iter.next(); + map_next(&mut iter); assert iter.get().unwrap() == (&x1, &y1); - iter = iter.next(); + map_next(&mut iter); assert iter.get().unwrap() == (&x2, &y2); - iter = iter.next(); + map_next(&mut iter); assert iter.get().unwrap() == (&x3, &y3); - iter = iter.next(); + map_next(&mut iter); assert iter.get().unwrap() == (&x4, &y4); - iter = iter.next(); + map_next(&mut iter); assert iter.get().unwrap() == (&x5, &y5); - iter = iter.next(); + map_next(&mut iter); assert iter.get().is_none(); } } From 16941687839a4fa06e57d1d1cf36a3ccbc0257e1 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 6 Feb 2013 02:34:15 -0500 Subject: [PATCH 11/14] update treemap FIXME --- src/libstd/treemap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 610f2f5a59c2..b234f9b0f3da 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -963,7 +963,7 @@ mod test_treemap { let m = m; let mut iter = m.iter(); - // FIXME: #4492 (ICE): iter.next() == Some((&x1, &y1)) + // FIXME: #4492 (ICE): iter.get() == Some((&x1, &y1)) map_next(&mut iter); assert iter.get().unwrap() == (&x1, &y1); From bdfb930f3412bcbf792bd8ab10f40b6560663a5f Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 6 Feb 2013 02:39:47 -0500 Subject: [PATCH 12/14] treemap: make map_next and set_next public --- src/libstd/treemap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index b234f9b0f3da..3cc287b16a32 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -218,7 +218,7 @@ impl TreeMapIterator { /// Advance the iterator to the next node (in order). If this iterator /// is finished, does nothing. -fn map_next(iter: &mut TreeMapIterator/&a) { +pub fn map_next(iter: &mut TreeMapIterator/&a) { while !iter.stack.is_empty() || iter.node.is_some() { match *iter.node { Some(ref x) => { @@ -530,7 +530,7 @@ impl TreeSetIterator { /// Advance the iterator to the next node (in order). If this iterator is /// finished, does nothing. -fn set_next(iter: &mut TreeSetIterator/&a) { +pub fn set_next(iter: &mut TreeSetIterator/&a) { map_next(&mut iter.iter); } From dab2f2fac0d5147b088489abfbcf43714ed36156 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 6 Feb 2013 02:49:05 -0500 Subject: [PATCH 13/14] remove old snapshot workaround from smallintmap --- src/libstd/smallintmap.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index a21328b3d634..1cd35722ab46 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -116,8 +116,6 @@ pub impl SmallIntMap { } pub impl SmallIntMap { - // FIXME: #4733, remove after the next snapshot - #[cfg(stage2)] fn update_with_key(&mut self, key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool { match self.find(&key) { @@ -126,8 +124,6 @@ pub impl SmallIntMap { } } - // FIXME: #4733, remove after the next snapshot - #[cfg(stage2)] fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool { self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)) } From cf6c3d96fb1a7230cbdd8ebc77af30ba35b9e35a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 6 Feb 2013 15:37:34 -0800 Subject: [PATCH 14/14] librustc: Attempt to put out burning tree by fixing translation of unary negation in boolean constants. rs=burningtree --- src/librustc/lib/llvm.rs | 33 +++++++++++++++++------------ src/librustc/middle/trans/consts.rs | 13 +++++++++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 50f4fe43efd8..2e3967021c1d 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -445,14 +445,19 @@ pub extern mod llvm { Count: c_uint, Packed: Bool) -> ValueRef; - pub unsafe fn LLVMConstString(Str: *c_char, Length: c_uint, - DontNullTerminate: Bool) -> ValueRef; - pub unsafe fn LLVMConstArray(ElementTy: TypeRef, ConstantVals: *ValueRef, - Length: c_uint) -> ValueRef; + pub unsafe fn LLVMConstString(Str: *c_char, + Length: c_uint, + DontNullTerminate: Bool) + -> ValueRef; + pub unsafe fn LLVMConstArray(ElementTy: TypeRef, + ConstantVals: *ValueRef, + Length: c_uint) + -> ValueRef; pub unsafe fn LLVMConstStruct(ConstantVals: *ValueRef, - Count: c_uint, Packed: Bool) -> ValueRef; + Count: c_uint, + Packed: Bool) -> ValueRef; pub unsafe fn LLVMConstVector(ScalarConstantVals: *ValueRef, - Size: c_uint) -> ValueRef; + Size: c_uint) -> ValueRef; /* Constant expressions */ pub unsafe fn LLVMAlignOf(Ty: TypeRef) -> ValueRef; @@ -463,8 +468,8 @@ pub extern mod llvm { pub unsafe fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef; pub unsafe fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef; pub unsafe fn LLVMConstAdd(LHSConstant: ValueRef, - RHSConstant: ValueRef) - -> ValueRef; + RHSConstant: ValueRef) + -> ValueRef; pub unsafe fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; @@ -475,14 +480,14 @@ pub extern mod llvm { RHSConstant: ValueRef) -> ValueRef; pub unsafe fn LLVMConstSub(LHSConstant: ValueRef, - RHSConstant: ValueRef) - -> ValueRef; + RHSConstant: ValueRef) + -> ValueRef; pub unsafe fn LLVMConstNSWSub(LHSConstant: ValueRef, - RHSConstant: ValueRef) - -> ValueRef; + RHSConstant: ValueRef) + -> ValueRef; pub unsafe fn LLVMConstNUWSub(LHSConstant: ValueRef, - RHSConstant: ValueRef) - -> ValueRef; + RHSConstant: ValueRef) + -> ValueRef; pub unsafe fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef) -> ValueRef; diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 12340101d9e5..34f1f1f2314f 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -204,7 +204,18 @@ pub fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { ast::box(_) | ast::uniq(_) | ast::deref => const_deref(cx, te), - ast::not => llvm::LLVMConstNot(te), + ast::not => { + match ty::get(ty).sty { + ty::ty_bool => { + // Somewhat questionable, but I believe this is + // correct. + let te = llvm::LLVMConstTrunc(te, T_i1()); + let te = llvm::LLVMConstNot(te); + llvm::LLVMConstZExt(te, T_bool()) + } + _ => llvm::LLVMConstNot(te), + } + } ast::neg => { if is_float { llvm::LLVMConstFNeg(te) } else { llvm::LLVMConstNeg(te) }