fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                              lhs: ValueRef,
                              rhs: ValueRef,
                              rhs_t: Ty<'tcx>,
                              debug_loc: DebugLoc)
                              -> Result<'blk, 'tcx> {
    fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                               lhs: ValueRef,
                               rhs: ValueRef,
                               rhs_t: Ty<'tcx>,
                               debug_loc: DebugLoc)
                               -> Result<'blk, 'tcx> {
        let did = langcall(cx,
                           None,
                           &format!("comparison of `{}`",
                                   cx.ty_to_string(rhs_t)),
                           StrEqFnLangItem);
        let t = ty::mk_str_slice(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), ast::MutImmutable);
        // The comparison function gets the slices by value, so we have to make copies here. Even
        // if the function doesn't write through the pointer, things like lifetime intrinsics
        // require that we do this properly
        let lhs_arg = alloc_ty(cx, t, "lhs");
        let rhs_arg = alloc_ty(cx, t, "rhs");
        memcpy_ty(cx, lhs_arg, lhs, t);
        memcpy_ty(cx, rhs_arg, rhs, t);
        let res = callee::trans_lang_call(cx, did, &[lhs_arg, rhs_arg], None, debug_loc);
        call_lifetime_end(res.bcx, lhs_arg);
        call_lifetime_end(res.bcx, rhs_arg);

        res
    }

    let _icx = push_ctxt("compare_values");
    if ty::type_is_scalar(rhs_t) {
        let cmp = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq, debug_loc);
        return Result::new(cx, cmp);
    }

    match rhs_t.sty {
        ty::ty_rptr(_, mt) => match mt.ty.sty {
            ty::ty_str => compare_str(cx, lhs, rhs, rhs_t, debug_loc),
            ty::ty_vec(ty, _) => match ty.sty {
                ty::ty_uint(ast::TyU8) => {
                    // NOTE: cast &[u8] to &str and abuse the str_eq lang item,
                    // which calls memcmp().
                    let t = ty::mk_str_slice(cx.tcx(),
                                             cx.tcx().mk_region(ty::ReStatic),
                                             ast::MutImmutable);
                    let lhs = BitCast(cx, lhs, type_of::type_of(cx.ccx(), t).ptr_to());
                    let rhs = BitCast(cx, rhs, type_of::type_of(cx.ccx(), t).ptr_to());
                    compare_str(cx, lhs, rhs, rhs_t, debug_loc)
                },
                _ => cx.sess().bug("only byte strings supported in compare_values"),
            },
            _ => cx.sess().bug("only string and byte strings supported in compare_values"),
        },
        _ => cx.sess().bug("only scalars, byte strings, and strings supported in compare_values"),
    }
}
// Compiles a comparison between two things.
Compiles a comparison between two things.
Compiles a comparison between two things .
fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                              lhs: ValueRef,
                              rhs: ValueRef,
                              rhs_t: Ty<'tcx>,
                              debug_loc: DebugLoc)
                              -> Result<'blk, 'tcx> {
    fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                               lhs: ValueRef,
                               rhs: ValueRef,
                               rhs_t: Ty<'tcx>,
                               debug_loc: DebugLoc)
                               -> Result<'blk, 'tcx> {
        let did = langcall(cx,
                           None,
                           &format!("comparison of `{}`",
                                   cx.ty_to_string(rhs_t)),
                           StrEqFnLangItem);
        let t = ty::mk_str_slice(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), ast::MutImmutable);
        // The comparison function gets the slices by value, so we have to make copies here. Even
        // if the function doesn't write through the pointer, things like lifetime intrinsics
        // require that we do this properly
        let lhs_arg = alloc_ty(cx, t, "lhs");
        let rhs_arg = alloc_ty(cx, t, "rhs");
        memcpy_ty(cx, lhs_arg, lhs, t);
        memcpy_ty(cx, rhs_arg, rhs, t);
        let res = callee::trans_lang_call(cx, did, &[lhs_arg, rhs_arg], None, debug_loc);
        call_lifetime_end(res.bcx, lhs_arg);
        call_lifetime_end(res.bcx, rhs_arg);
        res
    }
    let _icx = push_ctxt("compare_values");
    if ty::type_is_scalar(rhs_t) {
        let cmp = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq, debug_loc);
        return Result::new(cx, cmp);
    }
    match rhs_t.sty {
        ty::ty_rptr(_, mt) => match mt.ty.sty {
            ty::ty_str => compare_str(cx, lhs, rhs, rhs_t, debug_loc),
            ty::ty_vec(ty, _) => match ty.sty {
                ty::ty_uint(ast::TyU8) => {
                    // NOTE: cast &[u8] to &str and abuse the str_eq lang item,
                    // which calls memcmp().
                    let t = ty::mk_str_slice(cx.tcx(),
                                             cx.tcx().mk_region(ty::ReStatic),
                                             ast::MutImmutable);
                    let lhs = BitCast(cx, lhs, type_of::type_of(cx.ccx(), t).ptr_to());
                    let rhs = BitCast(cx, rhs, type_of::type_of(cx.ccx(), t).ptr_to());
                    compare_str(cx, lhs, rhs, rhs_t, debug_loc)
                },
                _ => cx.sess().bug("only byte strings supported in compare_values"),
            },
            _ => cx.sess().bug("only string and byte strings supported in compare_values"),
        },
        _ => cx.sess().bug("only scalars, byte strings, and strings supported in compare_values"),
    }
}
fn compare_values < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > , lhs : ValueRef , rhs : ValueRef , rhs_t : Ty < ' tcx > , debug_loc : DebugLoc ) -> Result < ' blk , ' tcx > { fn compare_str < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > , lhs : ValueRef , rhs : ValueRef , rhs_t : Ty < ' tcx > , debug_loc : DebugLoc ) -> Result < ' blk , ' tcx > { let did = langcall ( cx , None , & format ! ( " " cx ty_to_string ( rhs_t ) ) , StrEqFnLangItem ) ; let t = ty :: mk_str_slice ( cx . tcx ( ) , cx . tcx ( ) . mk_region ( ty :: ReStatic ) , ast :: MutImmutable ) ; // The comparison function gets the slices by value, so we have to make copies here. Even // if the function doesn't write through the pointer, things like lifetime intrinsics // require that we do this properly let lhs_arg = alloc_ty ( cx , t , " " ) ; let rhs_arg = alloc_ty ( cx , t , " " ) ; memcpy_ty ( cx , lhs_arg , lhs , t ) ; memcpy_ty ( cx , rhs_arg , rhs , t ) ; let res = callee :: trans_lang_call ( cx , did , & [ lhs_arg , rhs_arg ] , None , debug_loc ) ; call_lifetime_end ( res . bcx , lhs_arg ) ; call_lifetime_end ( res . bcx , rhs_arg ) ; res } let _icx = push_ctxt ( " " ) ; if ty :: type_is_scalar ( rhs_t ) { let cmp = compare_scalar_types ( cx , lhs , rhs , rhs_t , ast :: BiEq , debug_loc ) ; return Result :: new ( cx , cmp ) ; } match rhs_t . sty { ty :: ty_rptr ( _ , mt ) => match mt . ty . sty { ty :: ty_str => compare_str ( cx , lhs , rhs , rhs_t , debug_loc ) , ty :: ty_vec ( ty , _ ) => match ty . sty { ty :: ty_uint ( ast :: TyU8 ) => { // NOTE: cast &[u8] to &str and abuse the str_eq lang item, // which calls memcmp(). let t = ty :: mk_str_slice ( cx . tcx ( ) , cx . tcx ( ) . mk_region ( ty :: ReStatic ) , ast :: MutImmutable ) ; let lhs = BitCast ( cx , lhs , type_of :: type_of ( cx . ccx ( ) , t ) . ptr_to ( ) ) ; let rhs = BitCast ( cx , rhs , type_of :: type_of ( cx . ccx ( ) , t ) . ptr_to ( ) ) ; compare_str ( cx , lhs , rhs , rhs_t , debug_loc ) } , _ => cx . sess ( ) . bug ( " " ) , } , _ => cx . sess ( ) . bug ( " " ) , } , _ => cx . sess ( ) . bug ( " " ) , } }
Compiles a comparison between two things.
Compiles a comparison between two things .
cx
Block<'blk, 'tcx>
lhs
ValueRef
rhs
ValueRef
rhs_t
Ty<'tcx>
debug_loc
DebugLoc
cx
Block<'blk, 'tcx>
lhs
ValueRef
rhs
ValueRef
rhs_t
Ty<'tcx>
debug_loc
DebugLoc