use hair::*;
use rustc_data_structures::fnv::FnvHashMap;
+use rustc_const_math::ConstInt;
use hair::cx::Cx;
use hair::cx::block;
use hair::cx::to_ref::ToRef;
-use rustc::front::map;
-use rustc::middle::def::Def;
-use rustc::middle::const_eval;
+use rustc::hir::map;
+use rustc::hir::def::Def;
+use rustc::middle::const_val::ConstVal;
+use rustc_const_eval as const_eval;
use rustc::middle::region::CodeExtent;
-use rustc::middle::pat_util;
-use rustc::middle::ty::{self, VariantDef, Ty};
+use rustc::hir::pat_util;
+use rustc::ty::{self, VariantDef, Ty};
use rustc::mir::repr::*;
-use rustc_front::hir;
-use rustc_front::util as hir_util;
-use syntax::parse::token;
+use rustc::hir;
use syntax::ptr::P;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
let method = method_callee(cx, self, ty::MethodCall::expr(self.id));
let sig = match method.ty.sty {
- ty::TyBareFn(_, fn_ty) => &fn_ty.sig,
- _ => cx.tcx.sess.span_bug(self.span, "type of method is not an fn")
+ ty::TyFnDef(_, _, fn_ty) => &fn_ty.sig,
+ _ => span_bug!(self.span, "type of method is not an fn")
};
let sig = cx.tcx.no_late_bound_regions(sig).unwrap_or_else(|| {
- cx.tcx.sess.span_bug(self.span, "method call has late-bound regions")
+ span_bug!(self.span, "method call has late-bound regions")
});
assert_eq!(sig.inputs.len(), 2);
hir::ExprAddrOf(mutbl, ref expr) => {
let region = match expr_ty.sty {
ty::TyRef(r, _) => r,
- _ => cx.tcx.sess.span_bug(expr.span, "type of & not region"),
+ _ => span_bug!(expr.span, "type of & not region"),
};
ExprKind::Borrow {
region: *region,
hir::ExprAssignOp(op, ref lhs, ref rhs) => {
if cx.tcx.is_method_call(self.id) {
- let pass_args = if hir_util::is_by_value_binop(op.node) {
+ let pass_args = if op.node.is_by_value() {
PassArgs::ByValue
} else {
PassArgs::ByRef
hir::ExprBinary(op, ref lhs, ref rhs) => {
if cx.tcx.is_method_call(self.id) {
- let pass_args = if hir_util::is_by_value_binop(op.node) {
+ let pass_args = if op.node.is_by_value() {
PassArgs::ByValue
} else {
PassArgs::ByRef
}
}
- hir::ExprUnary(op, ref arg) => {
+ hir::ExprUnary(hir::UnOp::UnNot, ref arg) => {
if cx.tcx.is_method_call(self.id) {
overloaded_operator(cx, self, ty::MethodCall::expr(self.id),
PassArgs::ByValue, arg.to_ref(), vec![])
} else {
- // FIXME overflow
- let op = match op {
- hir::UnOp::UnNot => UnOp::Not,
- hir::UnOp::UnNeg => UnOp::Neg,
- hir::UnOp::UnDeref => {
- cx.tcx.sess.span_bug(
- self.span,
- "UnDeref should have been handled elsewhere");
- }
- };
ExprKind::Unary {
- op: op,
+ op: UnOp::Not,
arg: arg.to_ref(),
}
}
}
+ hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => {
+ if cx.tcx.is_method_call(self.id) {
+ overloaded_operator(cx, self, ty::MethodCall::expr(self.id),
+ PassArgs::ByValue, arg.to_ref(), vec![])
+ } else {
+ // FIXME runtime-overflow
+ if let hir::ExprLit(_) = arg.node {
+ ExprKind::Literal {
+ literal: cx.const_eval_literal(self),
+ }
+ } else {
+ ExprKind::Unary {
+ op: UnOp::Neg,
+ arg: arg.to_ref(),
+ }
+ }
+ }
+ }
+
hir::ExprStruct(_, ref fields, ref base) => {
match expr_ty.sty {
ty::TyStruct(adt, substs) => {
}
}
ref def => {
- cx.tcx.sess.span_bug(
+ span_bug!(
self.span,
- &format!("unexpected def: {:?}", def));
+ "unexpected def: {:?}",
+ def);
}
}
}
_ => {
- cx.tcx.sess.span_bug(
+ span_bug!(
self.span,
- &format!("unexpected type for struct literal: {:?}", expr_ty));
+ "unexpected type for struct literal: {:?}",
+ expr_ty);
}
}
}
let (def_id, substs) = match closure_ty.sty {
ty::TyClosure(def_id, ref substs) => (def_id, substs),
_ => {
- cx.tcx.sess.span_bug(self.span,
- &format!("closure expr w/o closure type: {:?}",
- closure_ty));
+ span_bug!(self.span,
+ "closure expr w/o closure type: {:?}",
+ closure_ty);
}
};
let upvars = cx.tcx.with_freevars(self.id, |freevars| {
}
}
- hir::ExprRange(ref start, ref end) => {
- let range_ty = cx.tcx.expr_ty(self);
- let (adt_def, substs) = match range_ty.sty {
- ty::TyStruct(adt_def, substs) => (adt_def, substs),
- _ => {
- cx.tcx.sess.span_bug(self.span, "unexpanded ast");
- }
- };
-
- let field_expr_ref = |s: &'tcx P<hir::Expr>, name: &str| {
- let name = token::intern(name);
- let index = adt_def.variants[0].index_of_field_named(name).unwrap();
- FieldExprRef { name: Field::new(index), expr: s.to_ref() }
- };
-
- let start_field = start.as_ref()
- .into_iter()
- .map(|s| field_expr_ref(s, "start"));
-
- let end_field = end.as_ref()
- .into_iter()
- .map(|e| field_expr_ref(e, "end"));
-
- ExprKind::Adt {
- adt_def: adt_def,
- variant_index: 0,
- substs: substs,
- fields: start_field.chain(end_field).collect(),
- base: None,
- }
- }
-
hir::ExprPath(..) => {
convert_path_expr(cx, self)
}
- hir::ExprInlineAsm(ref asm) => {
- ExprKind::InlineAsm { asm: asm }
+ hir::ExprInlineAsm(ref asm, ref outputs, ref inputs) => {
+ ExprKind::InlineAsm {
+ asm: asm,
+ outputs: outputs.to_ref(),
+ inputs: inputs.to_ref()
+ }
}
// Now comes the rote stuff:
count: TypedConstVal {
ty: cx.tcx.expr_ty(c),
span: c.span,
- value: const_eval::eval_const_expr(cx.tcx, c)
+ value: match const_eval::eval_const_expr(cx.tcx, c) {
+ ConstVal::Integral(ConstInt::Usize(u)) => u,
+ other => bug!("constant evaluation of repeat count yielded {:?}", other),
+ },
}
},
hir::ExprRet(ref v) =>
ty::TyStruct(adt_def, _) =>
adt_def.variants[0].index_of_field_named(name.node),
ref ty =>
- cx.tcx.sess.span_bug(
+ span_bug!(
self.span,
- &format!("field of non-struct: {:?}", ty)),
+ "field of non-struct: {:?}",
+ ty),
};
let index = index.unwrap_or_else(|| {
- cx.tcx.sess.span_bug(
+ span_bug!(
self.span,
- &format!("no index found for field `{}`", name.node));
+ "no index found for field `{}`",
+ name.node)
});
ExprKind::Field { lhs: source.to_ref(), name: Field::new(index) }
}
Some(ty::FnConverging(&ty::TyS {
sty: ty::TyRef(region, mt), ..
})) => (region, mt.mutbl),
- _ => cx.tcx.sess.span_bug(
- expr.span, "autoderef returned bad type")
+ _ => span_bug!(expr.span, "autoderef returned bad type")
};
expr = Expr {
kind: ExprKind::Literal {
literal: Literal::Item {
def_id: callee.def_id,
- kind: ItemKind::Method,
substs: callee.substs,
},
},
let substs = cx.tcx.mk_substs(cx.tcx.node_id_item_substs(expr.id).substs);
// Otherwise there may be def_map borrow conflicts
let def = cx.tcx.def_map.borrow()[&expr.id].full_def();
- let (def_id, kind) = match def {
+ let def_id = match def {
// A regular function.
- Def::Fn(def_id) => (def_id, ItemKind::Function),
- Def::Method(def_id) => (def_id, ItemKind::Method),
+ Def::Fn(def_id) | Def::Method(def_id) => def_id,
Def::Struct(def_id) => match cx.tcx.node_id_to_type(expr.id).sty {
// A tuple-struct constructor. Should only be reached if not called in the same
// expression.
- ty::TyBareFn(..) => (def_id, ItemKind::Function),
+ ty::TyFnDef(..) => def_id,
// A unit struct which is used as a value. We return a completely different ExprKind
// here to account for this special case.
ty::TyStruct(adt_def, substs) => return ExprKind::Adt {
fields: vec![],
base: None
},
- ref sty => panic!("unexpected sty: {:?}", sty)
+ ref sty => bug!("unexpected sty: {:?}", sty)
},
Def::Variant(enum_id, variant_id) => match cx.tcx.node_id_to_type(expr.id).sty {
// A variant constructor. Should only be reached if not called in the same
// expression.
- ty::TyBareFn(..) => (variant_id, ItemKind::Function),
+ ty::TyFnDef(..) => variant_id,
// A unit variant, similar special case to the struct case above.
ty::TyEnum(adt_def, substs) => {
debug_assert!(adt_def.did == enum_id);
base: None
};
},
- ref sty => panic!("unexpected sty: {:?}", sty)
+ ref sty => bug!("unexpected sty: {:?}", sty)
},
Def::Const(def_id) |
Def::AssociatedConst(def_id) => {
- if let Some(v) = cx.try_const_eval_literal(expr) {
- return ExprKind::Literal { literal: v };
- } else {
- (def_id, ItemKind::Constant)
+ let substs = Some(cx.tcx.node_id_item_substs(expr.id).substs);
+ if let Some((e, _)) = const_eval::lookup_const_by_id(cx.tcx, def_id, substs) {
+ // FIXME ConstVal can't be yet used with adjustments, as they would be lost.
+ if !cx.tcx.tables.borrow().adjustments.contains_key(&e.id) {
+ if let Some(v) = cx.try_const_eval_literal(e) {
+ return ExprKind::Literal { literal: v };
+ }
+ }
}
+ def_id
}
Def::Static(node_id, _) => return ExprKind::StaticRef {
def @ Def::Upvar(..) => return convert_var(cx, expr, def),
def =>
- cx.tcx.sess.span_bug(
+ span_bug!(
expr.span,
- &format!("def `{:?}` not yet implemented", def)),
+ "def `{:?}` not yet implemented",
+ def),
};
ExprKind::Literal {
- literal: Literal::Item { def_id: def_id, kind: kind, substs: substs }
+ literal: Literal::Item { def_id: def_id, substs: substs }
}
}
match expr.node {
hir::ExprClosure(_, _, ref body) => body.id,
_ => {
- cx.tcx.sess.span_bug(expr.span, "closure expr is not a closure expr");
+ span_bug!(expr.span, "closure expr is not a closure expr");
}
}
}
_ => {
- cx.tcx.sess.span_bug(expr.span, "ast-map has garbage for closure expr");
+ span_bug!(expr.span, "ast-map has garbage for closure expr");
}
};
let region = cx.tcx.mk_region(region);
let self_expr = match cx.tcx.closure_kind(cx.tcx.map.local_def_id(closure_expr_id)) {
- ty::ClosureKind::FnClosureKind => {
+ ty::ClosureKind::Fn => {
let ref_closure_ty =
cx.tcx.mk_ref(region,
ty::TypeAndMut { ty: closure_ty,
}
}
}
- ty::ClosureKind::FnMutClosureKind => {
+ ty::ClosureKind::FnMut => {
let ref_closure_ty =
cx.tcx.mk_ref(region,
ty::TypeAndMut { ty: closure_ty,
}
}
}
- ty::ClosureKind::FnOnceClosureKind => {
+ ty::ClosureKind::FnOnce => {
Expr {
ty: closure_ty,
temp_lifetime: temp_lifetime,
let upvar_capture = match cx.tcx.upvar_capture(upvar_id) {
Some(c) => c,
None => {
- cx.tcx.sess.span_bug(
+ span_bug!(
expr.span,
- &format!("no upvar_capture for {:?}", upvar_id));
+ "no upvar_capture for {:?}",
+ upvar_id);
}
};
match upvar_capture {
}
}
- _ => cx.tcx.sess.span_bug(expr.span, "type of & not region"),
+ _ => span_bug!(expr.span, "type of & not region"),
}
}
hir::BinOp_::BiNe => BinOp::Ne,
hir::BinOp_::BiGe => BinOp::Ge,
hir::BinOp_::BiGt => BinOp::Gt,
- _ => panic!("no equivalent for ast binop {:?}", op),
+ _ => bug!("no equivalent for ast binop {:?}", op),
}
}
fn capture_freevar<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
closure_expr: &'tcx hir::Expr,
- freevar: &ty::Freevar,
+ freevar: &hir::Freevar,
freevar_ty: Ty<'tcx>)
-> ExprRef<'tcx> {
let id_var = freevar.def.var_id();
match cx.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
Some(Def::Label(loop_id)) => cx.tcx.region_maps.node_extent(loop_id),
d => {
- cx.tcx.sess.span_bug(expr.span, &format!("loop scope resolved to {:?}", d));
+ span_bug!(expr.span, "loop scope resolved to {:?}", d);
}
}
}