diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index d550ccbf61a..e07dcf6ba9e 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -190,4 +190,6 @@ fn main() { [] => assert_eq!(0u32, 1), [_, ref y..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize), } + + assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); } diff --git a/src/base.rs b/src/base.rs index 6427c756ac8..0c78613c245 100644 --- a/src/base.rs +++ b/src/base.rs @@ -586,8 +586,24 @@ fn trans_stmt<'a, 'tcx: 'a>( _ => unimpl!("rval misc {:?} {:?}", from_ty, to_ty), } } - Rvalue::Cast(CastKind::ClosureFnPointer, operand, ty) => { - unimplemented!("rval closure_fn_ptr {:?} {:?}", operand, ty) + Rvalue::Cast(CastKind::ClosureFnPointer, operand, _ty) => { + let operand = trans_operand(fx, operand); + match operand.layout().ty.sty { + ty::Closure(def_id, substs) => { + let instance = rustc_mir::monomorphize::resolve_closure( + fx.tcx, + def_id, + substs, + ty::ClosureKind::FnOnce, + ); + let func_ref = fx.get_function_ref(instance); + let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref); + lval.write_cvalue(fx, CValue::ByVal(func_addr, lval.layout())); + } + _ => { + bug!("{} cannot be cast to a fn ptr", operand.layout().ty) + } + } } Rvalue::Cast(CastKind::Unsize, operand, _ty) => { let operand = trans_operand(fx, operand);