use crate::hair::util::UserAnnotatedTyHelpers;
use rustc_index::vec::Idx;
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
-use rustc::mir::interpret::{GlobalId, ErrorHandled};
+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(),
}
}
- 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),