diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 08826013ebc..d3844b89b06 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -514,17 +514,29 @@ fn convert_arm<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, arm: &'tcx hir::Arm) -> Arm< fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> ExprKind<'tcx> { let substs = cx.tcx.mk_substs(cx.tcx.node_id_item_substs(expr.id).substs); - match cx.tcx.def_map.borrow()[&expr.id].full_def() { + // Otherwise there may be def_map borrow conflicts + let def = cx.tcx.def_map.borrow()[&expr.id].full_def(); + match def { def::DefVariant(_, def_id, false) | def::DefStruct(def_id) | def::DefFn(def_id, _) | - def::DefConst(def_id) | - def::DefMethod(def_id) | - def::DefAssociatedConst(def_id) => + def::DefMethod(def_id) => ExprKind::Literal { literal: Literal::Item { def_id: def_id, substs: substs } }, + def::DefConst(def_id) | + def::DefAssociatedConst(def_id) => { + if let Some(v) = cx.try_const_eval_literal(expr) { + ExprKind::Literal { literal: v } + } else { + ExprKind::Literal { + literal: Literal::Item { def_id: def_id, substs: substs } + } + } + } + + def::DefStatic(node_id, _) => ExprKind::StaticRef { id: node_id, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 8c19e620e46..5528f2de577 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -76,6 +76,13 @@ impl<'a,'tcx:'a> Cx<'a, 'tcx> { Literal::Value { value: const_eval::eval_const_expr(self.tcx, e) } } + pub fn try_const_eval_literal(&mut self, e: &hir::Expr) -> Option> { + let hint = const_eval::EvalHint::ExprTypeChecked; + const_eval::eval_const_expr_partial(self.tcx, e, hint, None) + .ok() + .map(|v| Literal::Value { value: v }) + } + pub fn partial_eq(&mut self, ty: Ty<'tcx>) -> ItemRef<'tcx> { let eq_def_id = self.tcx.lang_items.eq_trait().unwrap(); self.cmp_method_ref(eq_def_id, "eq", ty)