Merge branch 'incoming' of https://github.com/mozilla/rust into incoming

This commit is contained in:
Brendan Zabarauskas 2013-02-07 22:55:23 +11:00
commit 17a14fe0e9
21 changed files with 369 additions and 153 deletions

View File

@ -1,3 +1,9 @@
Version 0.6 (?)
---------------------------
* Libraries
* `core::send_map` renamed to `core::hashmap`
Version 0.5 (December 2012)
---------------------------

View File

@ -49,9 +49,8 @@ pub mod linear {
buckets: ~[Option<Bucket<K, V>>],
}
// FIXME(#3148) -- we could rewrite FoundEntry
// to have type Option<&Bucket<K, V>> which would be nifty
// However, that won't work until #3148 is fixed
// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
// 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<K, V> = bkt;
Some(&bkt.value)
}
None => {

View File

@ -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<T: Rand> Option<T>: Rand {
static fn rand(rng: rand::Rng) -> Option<T> {
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<T> {
/// Extension methods for random number generators
impl Rng {
/// Return a random value for a Rand type
fn gen<T: Rand>() -> T {
Rand::rand(self)
}
/// Return a random int
fn gen_int() -> int {

View File

@ -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;

View File

@ -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| {

View File

@ -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)
}
@ -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)
}
@ -766,7 +775,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);
@ -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]);
}

View File

@ -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(&copy bcx.fcx.loop_ret) |lret| {
Store(bcx, C_bool(true), lret.flagptr);
Store(bcx, C_bool(false), bcx.fcx.llretptr);

View File

@ -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<ast::node_id, ValueRef>,
exp_map2: resolve::ExportMap2,
@ -759,7 +761,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 +1111,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 +1441,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

View File

@ -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) }

View File

@ -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)
}

View File

@ -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 {

View File

@ -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()

View File

@ -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)
}

View File

@ -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

View File

@ -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()
}

View File

@ -116,8 +116,6 @@ pub impl<V> SmallIntMap<V> {
}
pub impl<V: Copy> SmallIntMap<V> {
// 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<V: Copy> SmallIntMap<V> {
}
}
// 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))
}

View File

@ -49,8 +49,8 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: 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<K: Ord, V>(a: &TreeMap<K, V>, b: &TreeMap<K, V>) -> 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; }
@ -142,7 +142,6 @@ impl <K: Ord, V> TreeMap<K, V>: Map<K, V> {
loop {
match *current {
Some(ref r) => {
let r: &self/~TreeNode<K, V> = r; // FIXME: #3148
if *key < r.key {
current = &r.left;
} else if r.key < *key {
@ -211,32 +210,30 @@ impl <K: Ord, V> TreeMapIterator<K, V> {
// 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<K, V> {
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.
pub fn map_next<K: Ord, V>(iter: &mut TreeMapIterator/&a<K, V>) {
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<T> {
@ -298,18 +295,18 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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;
@ -329,8 +326,8 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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() {
@ -346,10 +343,10 @@ impl <T: Ord> TreeSet<T>: Set<T> {
}
if !(a1 < b1) {
y = y.next();
set_next(&mut y);
b = y.get();
}
x = x.next();
set_next(&mut x);
a = x.get();
}
}
@ -362,15 +359,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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 }
}
}
@ -379,11 +376,11 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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();
}
}
@ -397,15 +394,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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 }
}
}
@ -414,21 +411,21 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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 }
}
}
}
@ -439,8 +436,8 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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();
@ -448,13 +445,13 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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();
}
}
@ -467,15 +464,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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 }
}
}
@ -484,15 +481,15 @@ impl <T: Ord> TreeSet<T>: Set<T> {
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();
}
}
@ -525,16 +522,16 @@ impl <T: Ord> TreeSetIterator<T> {
/// 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<T> {
TreeSetIterator { iter: self.iter.next() }
}
/// Advance the iterator to the next node (in order). If this iterator is
/// finished, does nothing.
pub fn set_next<T: Ord>(iter: &mut TreeSetIterator/&a<T>) {
map_next(&mut iter.iter);
}
// Nodes keep track of their level in the tree, starting at 1 in the
@ -746,8 +743,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);
@ -966,20 +963,20 @@ 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))
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();
}
}

View File

@ -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;

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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();
}

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;
}

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;
}