use crate::hair::util::UserAnnotatedTyHelpers;
use rustc_index::vec::Idx;
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
-use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
+use rustc::mir::interpret::{GlobalId, ErrorHandled, Scalar};
use rustc::ty::{self, AdtKind, Ty};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
use rustc::ty::subst::{InternalSubsts, SubstsRef};
} else {
// FIXME overflow
match (op.node, cx.constness) {
- // FIXME(eddyb) use logical ops in constants when
- // they can handle that kind of control-flow.
- (hir::BinOpKind::And, hir::Constness::Const) => {
+ // Destroy control flow if `#![feature(const_if_match)]` is not enabled.
+ (hir::BinOpKind::And, hir::Constness::Const)
+ if !cx.tcx.features().const_if_match =>
+ {
cx.control_flow_destroyed.push((
op.span,
"`&&` operator".into(),
rhs: rhs.to_ref(),
}
}
- (hir::BinOpKind::Or, hir::Constness::Const) => {
+ (hir::BinOpKind::Or, hir::Constness::Const)
+ if !cx.tcx.features().const_if_match =>
+ {
cx.control_flow_destroyed.push((
op.span,
"`||` operator".into(),
}
}
- (hir::BinOpKind::And, hir::Constness::NotConst) => {
+ (hir::BinOpKind::And, _) => {
ExprKind::LogicalOp {
op: LogicalOp::And,
lhs: lhs.to_ref(),
rhs: rhs.to_ref(),
}
}
- (hir::BinOpKind::Or, hir::Constness::NotConst) => {
+ (hir::BinOpKind::Or, _) => {
ExprKind::LogicalOp {
op: LogicalOp::Or,
lhs: lhs.to_ref(),
convert_path_expr(cx, expr, res)
}
- hir::ExprKind::InlineAsm(ref asm, ref outputs, ref inputs) => {
+ hir::ExprKind::InlineAsm(ref asm) => {
ExprKind::InlineAsm {
- asm,
- outputs: outputs.to_ref(),
- inputs: inputs.to_ref(),
+ asm: &asm.inner,
+ outputs: asm.outputs_exprs.to_ref(),
+ inputs: asm.inputs_exprs.to_ref(),
}
}
let cast = if cx.tables().is_coercion_cast(source.hir_id) {
// Convert the lexpr to a vexpr.
ExprKind::Use { source: source.to_ref() }
+ } else if cx.tables().expr_ty(source).is_region_ptr() {
+ // Special cased so that we can type check that the element
+ // type of the source matches the pointed to type of the
+ // destination.
+ ExprKind::Pointer { source: source.to_ref(), cast: PointerCast::ArrayToPointer }
} else {
// check whether this is casting an enum variant discriminant
// to prevent cycles, we refer to the discriminant initializer
// and not the beginning of discriminants (which is always `0`)
let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
let lhs = mk_const(cx.tcx().mk_const(ty::Const {
- val: ConstValue::Unevaluated(did, substs),
+ val: ty::ConstKind::Unevaluated(did, substs),
ty: var_ty,
}));
let bin = ExprKind::Binary {
impl ToBorrowKind for hir::Mutability {
fn to_borrow_kind(&self) -> BorrowKind {
match *self {
- hir::MutMutable => BorrowKind::Mut { allow_two_phase_borrow: false },
- hir::MutImmutable => BorrowKind::Shared,
+ hir::Mutability::Mutable => BorrowKind::Mut { allow_two_phase_borrow: false },
+ hir::Mutability::Immutable => BorrowKind::Shared,
}
}
}
let local_def_id = cx.tcx.hir().local_def_id(hir_id);
let index = generics.param_def_id_to_index[&local_def_id];
let name = cx.tcx.hir().name(hir_id);
- let val = ConstValue::Param(ty::ParamConst::new(index, name));
+ let val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
ExprKind::Literal {
literal: cx.tcx.mk_const(
ty::Const {
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
ExprKind::Literal {
literal: cx.tcx.mk_const(ty::Const {
- val: ConstValue::Unevaluated(def_id, substs),
+ val: ty::ConstKind::Unevaluated(def_id, substs),
ty: cx.tables().node_type(expr.hir_id),
}),
user_ty,
}
}
- Res::Def(DefKind::Static, id) => ExprKind::StaticRef { id },
+ // We encode uses of statics as a `*&STATIC` where the `&STATIC` part is
+ // a constant reference (or constant raw pointer for `static mut`) in MIR
+ Res::Def(DefKind::Static, id) => {
+ let ty = cx.tcx.type_of(id);
+ let ty = if cx.tcx.is_mutable_static(id) {
+ cx.tcx.mk_mut_ptr(ty)
+ } else if cx.tcx.is_foreign_item(id) {
+ cx.tcx.mk_imm_ptr(ty)
+ } else {
+ cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_static, ty)
+ };
+ let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id);
+ let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
+ ExprKind::Deref { arg: Expr {
+ ty,
+ temp_lifetime,
+ span: expr.span,
+ kind: ExprKind::StaticRef {
+ literal: ty::Const::from_scalar(cx.tcx, Scalar::Ptr(ptr.into()), ty),
+ def_id: id,
+ }
+ }.to_ref() }
+ },
Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id),
let ref_closure_ty = cx.tcx.mk_ref(region,
ty::TypeAndMut {
ty: closure_ty,
- mutbl: hir::MutImmutable,
+ mutbl: hir::Mutability::Immutable,
});
Expr {
ty: closure_ty,
let ref_closure_ty = cx.tcx.mk_ref(region,
ty::TypeAndMut {
ty: closure_ty,
- mutbl: hir::MutMutable,
+ mutbl: hir::Mutability::Mutable,
});
Expr {
ty: closure_ty,