lower blanket unsafe block to actual cases of unsafe and adjust indents

This commit is contained in:
Oliver Schneider 2015-07-03 11:34:19 +02:00
parent a2b927c5a4
commit 106f3826e9

View File

@ -486,13 +486,12 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
.map(|e| const_expr(cx, &**e, param_substs, fn_args).0)
.collect()
};
unsafe {
let _icx = push_ctxt("const_expr");
match e.node {
ast::ExprLit(ref lit) => {
const_lit(cx, e, &**lit)
}
ast::ExprBinary(b, ref e1, ref e2) => {
let _icx = push_ctxt("const_expr");
match e.node {
ast::ExprLit(ref lit) => {
const_lit(cx, e, &**lit)
},
ast::ExprBinary(b, ref e1, ref e2) => {
/* Neither type is bottom, and we expect them to be unified
* already, so the following is safe. */
let (te1, ty) = const_expr(cx, &**e1, param_substs, fn_args);
@ -512,145 +511,136 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
check_binary_expr_validity(cx, e, ty, te1, te2);
match b.node {
ast::BiAdd => {
if is_float { llvm::LLVMConstFAdd(te1, te2) }
else { llvm::LLVMConstAdd(te1, te2) }
}
ast::BiSub => {
if is_float { llvm::LLVMConstFSub(te1, te2) }
else { llvm::LLVMConstSub(te1, te2) }
}
ast::BiMul => {
if is_float { llvm::LLVMConstFMul(te1, te2) }
else { llvm::LLVMConstMul(te1, te2) }
}
ast::BiDiv => {
if is_float { llvm::LLVMConstFDiv(te1, te2) }
else if signed { llvm::LLVMConstSDiv(te1, te2) }
else { llvm::LLVMConstUDiv(te1, te2) }
}
ast::BiRem => {
if is_float { llvm::LLVMConstFRem(te1, te2) }
else if signed { llvm::LLVMConstSRem(te1, te2) }
else { llvm::LLVMConstURem(te1, te2) }
}
ast::BiAnd => llvm::LLVMConstAnd(te1, te2),
ast::BiOr => llvm::LLVMConstOr(te1, te2),
ast::BiBitXor => llvm::LLVMConstXor(te1, te2),
ast::BiBitAnd => llvm::LLVMConstAnd(te1, te2),
ast::BiBitOr => llvm::LLVMConstOr(te1, te2),
ast::BiShl => {
let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
llvm::LLVMConstShl(te1, te2)
}
ast::BiShr => {
let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
}
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGt | ast::BiGe => {
if is_float {
let cmp = base::bin_op_to_fcmp_predicate(cx, b.node);
ConstFCmp(cmp, te1, te2)
} else {
let cmp = base::bin_op_to_icmp_predicate(cx, b.node, signed);
let bool_val = ConstICmp(cmp, te1, te2);
if is_simd {
// LLVM outputs an `< size x i1 >`, so we need to perform
// a sign extension to get the correctly sized type.
llvm::LLVMConstIntCast(bool_val, val_ty(te1).to_ref(), True)
} else {
bool_val
}
}
}
}
},
ast::ExprUnary(u, ref inner_e) => {
unsafe { match b.node {
ast::BiAdd if is_float => llvm::LLVMConstFAdd(te1, te2),
ast::BiAdd => llvm::LLVMConstAdd(te1, te2),
ast::BiSub if is_float => llvm::LLVMConstFSub(te1, te2),
ast::BiSub => llvm::LLVMConstSub(te1, te2),
ast::BiMul if is_float => llvm::LLVMConstFMul(te1, te2),
ast::BiMul => llvm::LLVMConstMul(te1, te2),
ast::BiDiv if is_float => llvm::LLVMConstFDiv(te1, te2),
ast::BiDiv if signed => llvm::LLVMConstSDiv(te1, te2),
ast::BiDiv => llvm::LLVMConstUDiv(te1, te2),
ast::BiRem if is_float => llvm::LLVMConstFRem(te1, te2),
ast::BiRem if signed => llvm::LLVMConstSRem(te1, te2),
ast::BiRem => llvm::LLVMConstURem(te1, te2),
ast::BiAnd => llvm::LLVMConstAnd(te1, te2),
ast::BiOr => llvm::LLVMConstOr(te1, te2),
ast::BiBitXor => llvm::LLVMConstXor(te1, te2),
ast::BiBitAnd => llvm::LLVMConstAnd(te1, te2),
ast::BiBitOr => llvm::LLVMConstOr(te1, te2),
ast::BiShl => {
let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
llvm::LLVMConstShl(te1, te2)
},
ast::BiShr => {
let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
if signed { llvm::LLVMConstAShr(te1, te2) }
else { llvm::LLVMConstLShr(te1, te2) }
},
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGt | ast::BiGe => {
if is_float {
let cmp = base::bin_op_to_fcmp_predicate(cx, b.node);
ConstFCmp(cmp, te1, te2)
} else {
let cmp = base::bin_op_to_icmp_predicate(cx, b.node, signed);
let bool_val = ConstICmp(cmp, te1, te2);
if is_simd {
// LLVM outputs an `< size x i1 >`, so we need to perform
// a sign extension to get the correctly sized type.
llvm::LLVMConstIntCast(bool_val, val_ty(te1).to_ref(), True)
} else {
bool_val
}
}
},
} } // unsafe { match b.node {
},
ast::ExprUnary(u, ref inner_e) => {
let (te, ty) = const_expr(cx, &**inner_e, param_substs, fn_args);
check_unary_expr_validity(cx, e, ty, te);
let is_float = ty.is_fp();
match u {
ast::UnUniq | ast::UnDeref => {
const_deref(cx, te, ty).0
}
ast::UnNot => llvm::LLVMConstNot(te),
ast::UnNeg => {
if is_float { llvm::LLVMConstFNeg(te) }
else { llvm::LLVMConstNeg(te) }
}
unsafe { match u {
ast::UnUniq | ast::UnDeref => const_deref(cx, te, ty).0,
ast::UnNot => llvm::LLVMConstNot(te),
ast::UnNeg if is_float => llvm::LLVMConstFNeg(te),
ast::UnNeg => llvm::LLVMConstNeg(te),
} }
},
ast::ExprField(ref base, field) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| {
let ix = cx.tcx().field_idx_strict(field.node.name, field_tys);
adt::const_get_field(cx, &*brepr, bv, discr, ix)
})
},
ast::ExprTupField(ref base, idx) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
expr::with_field_tys(cx.tcx(), bt, None, |discr, _| {
adt::const_get_field(cx, &*brepr, bv, discr, idx.node)
})
},
ast::ExprIndex(ref base, ref index) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let iv = match const_eval::eval_const_expr_partial(cx.tcx(), &**index, None) {
Ok(ConstVal::Int(i)) => i as u64,
Ok(ConstVal::Uint(u)) => u,
_ => cx.sess().span_bug(index.span,
"index is not an integer-constant expression")
};
let (arr, len) = match bt.sty {
ty::TyArray(_, u) => (bv, C_uint(cx, u)),
ty::TySlice(_) | ty::TyStr => {
let e1 = const_get_elt(cx, bv, &[0]);
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1]))
},
ty::TyRef(_, mt) => match mt.ty.sty {
ty::TyArray(_, u) => {
(const_deref_ptr(cx, bv), C_uint(cx, u))
},
_ => cx.sess().span_bug(base.span,
&format!("index-expr base must be a vector \
or string type, found {:?}",
bt)),
},
_ => cx.sess().span_bug(base.span,
&format!("index-expr base must be a vector \
or string type, found {:?}",
bt)),
};
let len = unsafe { llvm::LLVMConstIntGetZExtValue(len) as u64 };
let len = match bt.sty {
ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) => match ty.sty {
ty::TyStr => {
assert!(len > 0);
len - 1
},
_ => len,
},
_ => len,
};
if iv >= len {
// FIXME #3170: report this earlier on in the const-eval
// pass. Reporting here is a bit late.
cx.sess().span_err(e.span,
"const index-expr is out of bounds");
C_undef(type_of::type_of(cx, bt).element_type())
} else {
const_get_elt(cx, arr, &[iv as c_uint])
}
}
ast::ExprField(ref base, field) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| {
let ix = cx.tcx().field_idx_strict(field.node.name, field_tys);
adt::const_get_field(cx, &*brepr, bv, discr, ix)
})
}
ast::ExprTupField(ref base, idx) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
expr::with_field_tys(cx.tcx(), bt, None, |discr, _| {
adt::const_get_field(cx, &*brepr, bv, discr, idx.node)
})
}
ast::ExprIndex(ref base, ref index) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let iv = match const_eval::eval_const_expr_partial(cx.tcx(), &**index, None) {
Ok(ConstVal::Int(i)) => i as u64,
Ok(ConstVal::Uint(u)) => u,
_ => cx.sess().span_bug(index.span,
"index is not an integer-constant expression")
};
let (arr, len) = match bt.sty {
ty::TyArray(_, u) => (bv, C_uint(cx, u)),
ty::TySlice(_) | ty::TyStr => {
let e1 = const_get_elt(cx, bv, &[0]);
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1]))
}
ty::TyRef(_, mt) => match mt.ty.sty {
ty::TyArray(_, u) => {
(const_deref_ptr(cx, bv), C_uint(cx, u))
},
_ => cx.sess().span_bug(base.span,
&format!("index-expr base must be a vector \
or string type, found {:?}",
bt))
},
_ => cx.sess().span_bug(base.span,
&format!("index-expr base must be a vector \
or string type, found {:?}",
bt))
};
let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
let len = match bt.sty {
ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) => match ty.sty {
ty::TyStr => {
assert!(len > 0);
len - 1
}
_ => len
},
_ => len
};
if iv >= len {
// FIXME #3170: report this earlier on in the const-eval
// pass. Reporting here is a bit late.
cx.sess().span_err(e.span,
"const index-expr is out of bounds");
C_undef(type_of::type_of(cx, bt).element_type())
} else {
const_get_elt(cx, arr, &[iv as c_uint])
}
}
ast::ExprCast(ref base, _) => {
},
ast::ExprCast(ref base, _) => {
let t_cast = ety;
let llty = type_of::type_of(cx, t_cast);
let (v, t_expr) = const_expr(cx, &**base, param_substs, fn_args);
@ -671,136 +661,121 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
return addr;
}
}
match (CastTy::from_ty(cx.tcx(), t_expr).expect("bad input type for cast"),
CastTy::from_ty(cx.tcx(), t_cast).expect("bad output type for cast")) {
(CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
let repr = adt::represent_type(cx, t_expr);
let discr = adt::const_get_discrim(cx, &*repr, v);
let iv = C_integral(cx.int_type(), discr, false);
let s = adt::is_discr_signed(&*repr) as Bool;
llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
}
(CastTy::Int(_), CastTy::Int(_)) => {
let s = t_expr.is_signed() as Bool;
llvm::LLVMConstIntCast(v, llty.to_ref(), s)
}
(CastTy::Int(_), CastTy::Float) => {
if t_expr.is_signed() {
llvm::LLVMConstSIToFP(v, llty.to_ref())
} else {
llvm::LLVMConstUIToFP(v, llty.to_ref())
}
}
(CastTy::Float, CastTy::Float) => {
llvm::LLVMConstFPCast(v, llty.to_ref())
}
(CastTy::Float, CastTy::Int(IntTy::I)) => {
llvm::LLVMConstFPToSI(v, llty.to_ref())
}
(CastTy::Float, CastTy::Int(_)) => {
llvm::LLVMConstFPToUI(v, llty.to_ref())
}
(CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_))
| (CastTy::RPtr(_), CastTy::Ptr(_)) => {
ptrcast(v, llty)
}
(CastTy::FnPtr, CastTy::FnPtr) => ptrcast(v, llty), // isn't this a coercion?
(CastTy::Int(_), CastTy::Ptr(_)) => {
llvm::LLVMConstIntToPtr(v, llty.to_ref())
}
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
llvm::LLVMConstPtrToInt(v, llty.to_ref())
}
_ => {
cx.sess().impossible_case(e.span,
"bad combination of types for cast")
}
}
}
ast::ExprAddrOf(ast::MutImmutable, ref sub) => {
// If this is the address of some static, then we need to return
// the actual address of the static itself (short circuit the rest
// of const eval).
let mut cur = sub;
loop {
match cur.node {
ast::ExprParen(ref sub) => cur = sub,
ast::ExprBlock(ref blk) => {
unsafe { match (
CastTy::from_ty(cx.tcx(), t_expr).expect("bad input type for cast"),
CastTy::from_ty(cx.tcx(), t_cast).expect("bad output type for cast"),
) {
(CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
let repr = adt::represent_type(cx, t_expr);
let discr = adt::const_get_discrim(cx, &*repr, v);
let iv = C_integral(cx.int_type(), discr, false);
let s = adt::is_discr_signed(&*repr) as Bool;
llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
},
(CastTy::Int(_), CastTy::Int(_)) => {
let s = t_expr.is_signed() as Bool;
llvm::LLVMConstIntCast(v, llty.to_ref(), s)
},
(CastTy::Int(_), CastTy::Float) => {
if t_expr.is_signed() {
llvm::LLVMConstSIToFP(v, llty.to_ref())
} else {
llvm::LLVMConstUIToFP(v, llty.to_ref())
}
},
(CastTy::Float, CastTy::Float) => llvm::LLVMConstFPCast(v, llty.to_ref()),
(CastTy::Float, CastTy::Int(IntTy::I)) => llvm::LLVMConstFPToSI(v, llty.to_ref()),
(CastTy::Float, CastTy::Int(_)) => llvm::LLVMConstFPToUI(v, llty.to_ref()),
(CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_))
| (CastTy::RPtr(_), CastTy::Ptr(_)) => {
ptrcast(v, llty)
},
(CastTy::FnPtr, CastTy::FnPtr) => ptrcast(v, llty), // isn't this a coercion?
(CastTy::Int(_), CastTy::Ptr(_)) => llvm::LLVMConstIntToPtr(v, llty.to_ref()),
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
llvm::LLVMConstPtrToInt(v, llty.to_ref())
},
_ => {
cx.sess().impossible_case(e.span,
"bad combination of types for cast")
},
} } // unsafe { match ( ... ) {
},
ast::ExprAddrOf(ast::MutImmutable, ref sub) => {
// If this is the address of some static, then we need to return
// the actual address of the static itself (short circuit the rest
// of const eval).
let mut cur = sub;
loop {
match cur.node {
ast::ExprParen(ref sub) => cur = sub,
ast::ExprBlock(ref blk) => {
if let Some(ref sub) = blk.expr {
cur = sub;
} else {
break;
}
}
_ => break,
}
}
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
if let Some(def::DefStatic(def_id, _)) = opt_def {
get_static_val(cx, def_id, ety)
} else {
// If this isn't the address of a static, then keep going through
// normal constant evaluation.
let (v, _) = const_expr(cx, &**sub, param_substs, fn_args);
addr_of(cx, v, "ref")
}
}
ast::ExprAddrOf(ast::MutMutable, ref sub) => {
let (v, _) = const_expr(cx, &**sub, param_substs, fn_args);
addr_of_mut(cx, v, "ref_mut_slice")
}
ast::ExprTup(ref es) => {
let repr = adt::represent_type(cx, ety);
let vals = map_list(&es[..]);
adt::trans_const(cx, &*repr, 0, &vals[..])
}
ast::ExprStruct(_, ref fs, ref base_opt) => {
let repr = adt::represent_type(cx, ety);
},
_ => break,
}
}
let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
if let Some(def::DefStatic(def_id, _)) = opt_def {
get_static_val(cx, def_id, ety)
} else {
// If this isn't the address of a static, then keep going through
// normal constant evaluation.
let (v, _) = const_expr(cx, &**sub, param_substs, fn_args);
addr_of(cx, v, "ref")
}
},
ast::ExprAddrOf(ast::MutMutable, ref sub) => {
let (v, _) = const_expr(cx, &**sub, param_substs, fn_args);
addr_of_mut(cx, v, "ref_mut_slice")
},
ast::ExprTup(ref es) => {
let repr = adt::represent_type(cx, ety);
let vals = map_list(&es[..]);
adt::trans_const(cx, &*repr, 0, &vals[..])
},
ast::ExprStruct(_, ref fs, ref base_opt) => {
let repr = adt::represent_type(cx, ety);
let base_val = match *base_opt {
let base_val = match *base_opt {
Some(ref base) => Some(const_expr(cx, &**base, param_substs, fn_args)),
None => None
};
};
expr::with_field_tys(cx.tcx(), ety, Some(e.id), |discr, field_tys| {
let cs = field_tys.iter().enumerate()
.map(|(ix, &field_ty)| {
match fs.iter().find(|f| field_ty.name == f.ident.node.name) {
Some(ref f) => const_expr(cx, &*f.expr, param_substs, fn_args).0,
None => {
match base_val {
Some((bv, _)) => {
adt::const_get_field(cx, &*repr, bv,
discr, ix)
}
None => {
cx.sess().span_bug(e.span,
"missing struct field")
}
}
}
}
}).collect::<Vec<_>>();
if ety.is_simd(cx.tcx()) {
C_vector(&cs[..])
} else {
adt::trans_const(cx, &*repr, discr, &cs[..])
}
})
}
ast::ExprVec(ref es) => {
expr::with_field_tys(cx.tcx(), ety, Some(e.id), |discr, field_tys| {
let cs = field_tys.iter().enumerate()
.map(|(ix, &field_ty)| {
match (fs.iter().find(|f| field_ty.name == f.ident.node.name), base_val) {
(Some(ref f), _) => const_expr(cx, &*f.expr, param_substs, fn_args).0,
(_, Some((bv, _))) => adt::const_get_field(cx, &*repr, bv, discr, ix),
(_, None) => cx.sess().span_bug(e.span, "missing struct field"),
}
}).collect::<Vec<_>>();
if ety.is_simd(cx.tcx()) {
C_vector(&cs[..])
} else {
adt::trans_const(cx, &*repr, discr, &cs[..])
}
})
},
ast::ExprVec(ref es) => {
let unit_ty = ety.sequence_element_type(cx.tcx());
let llunitty = type_of::type_of(cx, unit_ty);
let vs = es.iter().map(|e| const_expr(cx, &**e, param_substs, fn_args).0)
.collect::<Vec<_>>();
let vs = es.iter()
.map(|e| const_expr(cx, &**e, param_substs, fn_args).0)
.collect::<Vec<_>>();
// If the vector contains enums, an LLVM array won't work.
if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
C_struct(cx, &vs[..], false)
} else {
C_array(llunitty, &vs[..])
}
}
ast::ExprRepeat(ref elem, ref count) => {
},
ast::ExprRepeat(ref elem, ref count) => {
let unit_ty = ety.sequence_element_type(cx.tcx());
let llunitty = type_of::type_of(cx, unit_ty);
let n = cx.tcx().eval_repeat_count(count);
@ -811,8 +786,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
} else {
C_array(llunitty, &vs[..])
}
}
ast::ExprPath(..) => {
},
ast::ExprPath(..) => {
let def = cx.tcx().def_map.borrow().get(&e.id).unwrap().full_def();
match def {
def::DefLocal(id) => {
@ -853,69 +828,68 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
or variant def")
}
}
}
ast::ExprCall(ref callee, ref args) => {
let mut callee = &**callee;
loop {
callee = match callee.node {
ast::ExprParen(ref inner) => &**inner,
ast::ExprBlock(ref block) => match block.expr {
Some(ref tail) => &**tail,
None => break
},
_ => break
};
}
let def = cx.tcx().def_map.borrow()[&callee.id].full_def();
let arg_vals = map_list(args);
match def {
def::DefFn(did, _) | def::DefMethod(did, _) => {
const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs)
}
def::DefStruct(_) => {
if ety.is_simd(cx.tcx()) {
C_vector(&arg_vals[..])
} else {
let repr = adt::represent_type(cx, ety);
adt::trans_const(cx, &*repr, 0, &arg_vals[..])
}
}
def::DefVariant(enum_did, variant_did, _) => {
let repr = adt::represent_type(cx, ety);
let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did);
adt::trans_const(cx,
&*repr,
vinfo.disr_val,
&arg_vals[..])
}
_ => cx.sess().span_bug(e.span, "expected a struct, variant, or const fn def")
}
}
ast::ExprMethodCall(_, _, ref args) => {
let arg_vals = map_list(args);
let method_call = ty::MethodCall::expr(e.id);
},
ast::ExprCall(ref callee, ref args) => {
let mut callee = &**callee;
loop {
callee = match callee.node {
ast::ExprParen(ref inner) => &**inner,
ast::ExprBlock(ref block) => match block.expr {
Some(ref tail) => &**tail,
None => break,
},
_ => break,
};
}
let def = cx.tcx().def_map.borrow()[&callee.id].full_def();
let arg_vals = map_list(args);
match def {
def::DefFn(did, _) | def::DefMethod(did, _) => {
const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs)
},
def::DefStruct(_) => {
if ety.is_simd(cx.tcx()) {
C_vector(&arg_vals[..])
} else {
let repr = adt::represent_type(cx, ety);
adt::trans_const(cx, &*repr, 0, &arg_vals[..])
}
},
def::DefVariant(enum_did, variant_did, _) => {
let repr = adt::represent_type(cx, ety);
let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did);
adt::trans_const(cx,
&*repr,
vinfo.disr_val,
&arg_vals[..])
},
_ => cx.sess().span_bug(e.span, "expected a struct, variant, or const fn def"),
}
},
ast::ExprMethodCall(_, _, ref args) => {
let arg_vals = map_list(args);
let method_call = ty::MethodCall::expr(e.id);
let method_did = cx.tcx().tables.borrow().method_map[&method_call].def_id;
const_fn_call(cx, MethodCallKey(method_call),
method_did, &arg_vals, param_substs)
}
ast::ExprParen(ref e) => const_expr(cx, &**e, param_substs, fn_args).0,
ast::ExprBlock(ref block) => {
const_fn_call(cx, MethodCallKey(method_call),
method_did, &arg_vals, param_substs)
},
ast::ExprParen(ref e) => const_expr(cx, &**e, param_substs, fn_args).0,
ast::ExprBlock(ref block) => {
match block.expr {
Some(ref expr) => const_expr(cx, &**expr, param_substs, fn_args).0,
None => C_nil(cx)
None => C_nil(cx),
}
}
ast::ExprClosure(_, ref decl, ref body) => {
},
ast::ExprClosure(_, ref decl, ref body) => {
closure::trans_closure_expr(closure::Dest::Ignore(cx),
decl,
body,
e.id,
param_substs);
C_null(type_of::type_of(cx, ety))
}
_ => cx.sess().span_bug(e.span,
"bad constant expression type in consts::const_expr")
}
},
_ => cx.sess().span_bug(e.span,
"bad constant expression type in consts::const_expr"),
}
}