UserTypeAnnotationIndex,
};
use crate::ty::print::{FmtPrinter, Printer};
+use crate::ty::adjustment::{PointerCast};
pub use crate::mir::interpret::AssertMessage;
Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
}
+
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
pub enum CastKind {
Misc,
-
- /// Converts unique, zero-sized type for a fn to fn()
- ReifyFnPointer,
-
- /// Converts non capturing closure to fn() or unsafe fn().
- /// It cannot convert a closure that requires unsafe.
- ClosureFnPointer(hir::Unsafety),
-
- /// Converts safe fn() to unsafe fn()
- UnsafeFnPointer,
-
- /// Coerces *mut T to *const T, preserving T.
- MutToConstPointer,
-
- /// "Unsize" -- convert a thin-or-fat pointer to a fat pointer.
- /// codegen must figure out the details once full monomorphization
- /// is known. For example, this could be used to cast from a
- /// `&[i32;N]` to a `&[i32]`, or a `Box<T>` to a `Box<dyn Trait>`
- /// (presuming `T: Trait`).
- Unsize,
+ Pointer(PointerCast),
}
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
use rustc_macros::HashStable;
+#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
+pub enum PointerCast {
+ ReifyFnPointer,
+ UnsafeFnPointer,
+ ClosureFnPointer(hir::Unsafety),
+ MutToConstPointer,
+ Unsize,
+}
+
/// Represents coercing a value to a different type of value.
///
/// We transform values by following a number of `Adjust` steps in order.
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, Ty, adjustment::{PointerCast}};
use rustc::ty::cast::{CastTy, IntTy};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir;
bx
}
- mir::Rvalue::Cast(mir::CastKind::Unsize, ref source, _) => {
+ mir::Rvalue::Cast(mir::CastKind::Pointer(PointerCast::Unsize), ref source, _) => {
// The destination necessarily contains a fat pointer, so if
// it's a scalar pair, it's a fat pointer or newtype thereof.
if bx.cx().is_backend_scalar_pair(dest.layout) {
let cast = bx.cx().layout_of(self.monomorphize(&mir_cast_ty));
let val = match *kind {
- mir::CastKind::ReifyFnPointer => {
+ mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
match operand.layout.ty.sty {
ty::FnDef(def_id, substs) => {
if bx.cx().tcx().has_attr(def_id, "rustc_args_required_const") {
}
}
}
- mir::CastKind::ClosureFnPointer(_) => {
+ mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => {
match operand.layout.ty.sty {
ty::Closure(def_id, substs) => {
let instance = monomorphize::resolve_closure(
}
}
}
- mir::CastKind::UnsafeFnPointer => {
+ mir::CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
// this is a no-op at the LLVM level
operand.val
}
- mir::CastKind::Unsize => {
+ mir::CastKind::Pointer(PointerCast::Unsize) => {
assert!(bx.cx().is_backend_scalar_pair(cast));
match operand.val {
OperandValue::Pair(lldata, llextra) => {
}
}
}
- mir::CastKind::MutToConstPointer
+ mir::CastKind::Pointer(PointerCast::MutToConstPointer)
| mir::CastKind::Misc if bx.cx().is_backend_scalar_pair(operand.layout) => {
if let OperandValue::Pair(data_ptr, meta) = operand.val {
if bx.cx().is_backend_scalar_pair(cast) {
bug!("Unexpected non-Pair operand")
}
}
- mir::CastKind::MutToConstPointer
+ mir::CastKind::Pointer(PointerCast::MutToConstPointer)
| mir::CastKind::Misc => {
assert!(bx.cx().is_backend_immediate(cast));
let ll_t_out = bx.cx().immediate_backend_type(cast);
Projection, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind,
};
use rustc::ty::{self, TyCtxt};
+use rustc::ty::adjustment::{PointerCast};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use syntax_pos::Span;
},
// If we see a unsized cast, then if it is our data we should check
// whether it is being cast to a trait object.
- Rvalue::Cast(CastKind::Unsize, operand, ty) => match operand {
+ Rvalue::Cast(
+ CastKind::Pointer(PointerCast::Unsize), operand, ty
+ ) => match operand {
Operand::Copy(Place::Base(PlaceBase::Local(from)))
| Operand::Move(Place::Base(PlaceBase::Local(from)))
if *from == target =>
use rustc::traits::query::type_op::custom::CustomTypeOp;
use rustc::traits::query::{Fallible, NoSolution};
use rustc::traits::{ObligationCause, PredicateObligations};
+use rustc::ty::adjustment::{PointerCast};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::{Subst, SubstsRef, UnpackedKind, UserSubsts};
use rustc::ty::{
Rvalue::Cast(cast_kind, op, ty) => {
match cast_kind {
- CastKind::ReifyFnPointer => {
+ CastKind::Pointer(PointerCast::ReifyFnPointer) => {
let fn_sig = op.ty(mir, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
}
}
- CastKind::ClosureFnPointer(unsafety) => {
+ CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
let sig = match op.ty(mir, tcx).sty {
ty::Closure(def_id, substs) => {
substs.closure_sig_ty(def_id, tcx).fn_sig(tcx)
}
}
- CastKind::UnsafeFnPointer => {
+ CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
let fn_sig = op.ty(mir, tcx).fn_sig(tcx);
// The type that we see in the fcx is like
}
}
- CastKind::Unsize => {
+ CastKind::Pointer(PointerCast::Unsize) => {
let &ty = ty;
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
);
}
- CastKind::MutToConstPointer => {
+ CastKind::Pointer(PointerCast::MutToConstPointer) => {
let ty_from = match op.ty(mir, tcx).sty {
ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
use rustc::mir::interpret::InterpError;
use rustc::mir::*;
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
+use rustc::ty::adjustment::{PointerCast};
use syntax_pos::Span;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
ExprKind::ReifyFnPointer { source } => {
let source = unpack!(block = this.as_operand(block, scope, source));
- block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty))
+ block.and(Rvalue::Cast(
+ CastKind::Pointer(PointerCast::ReifyFnPointer), source, expr.ty)
+ )
}
ExprKind::UnsafeFnPointer { source } => {
let source = unpack!(block = this.as_operand(block, scope, source));
- block.and(Rvalue::Cast(CastKind::UnsafeFnPointer, source, expr.ty))
+ block.and(Rvalue::Cast(
+ CastKind::Pointer(PointerCast::UnsafeFnPointer), source, expr.ty)
+ )
}
ExprKind::ClosureFnPointer { source, unsafety } => {
let source = unpack!(block = this.as_operand(block, scope, source));
- block.and(Rvalue::Cast(CastKind::ClosureFnPointer(unsafety), source, expr.ty))
+ block.and(Rvalue::Cast(
+ CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)), source, expr.ty)
+ )
}
ExprKind::MutToConstPointer { source } => {
let source = unpack!(block = this.as_operand(block, scope, source));
- block.and(Rvalue::Cast(CastKind::MutToConstPointer, source, expr.ty))
+ block.and(Rvalue::Cast(
+ CastKind::Pointer(PointerCast::MutToConstPointer), source, expr.ty)
+ )
}
ExprKind::Unsize { source } => {
let source = unpack!(block = this.as_operand(block, scope, source));
- block.and(Rvalue::Cast(CastKind::Unsize, source, expr.ty))
+ block.and(Rvalue::Cast(
+ CastKind::Pointer(PointerCast::Unsize), source, expr.ty)
+ )
}
ExprKind::Array { fields } => {
// (*) We would (maybe) be closer to codegen if we
use crate::hair::pattern::compare_const_vals;
use rustc_data_structures::bit_set::BitSet;
use rustc_data_structures::fx::FxHashMap;
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, Ty, adjustment::{PointerCast}};
use rustc::ty::util::IntTypeExt;
use rustc::ty::layout::VariantIdx;
use rustc::mir::*;
ty = tcx.mk_imm_ref(region, tcx.mk_slice(elem_ty));
if opt_ref_ty.is_some() {
place = self.temp(ty, test.span);
- self.cfg.push_assign(block, source_info, &place,
- Rvalue::Cast(CastKind::Unsize, val, ty));
+ self.cfg.push_assign(
+ block, source_info, &place, Rvalue::Cast(
+ CastKind::Pointer(PointerCast::Unsize), val, ty
+ )
+ );
}
if opt_ref_test_ty.is_some() {
let array = self.literal_operand(
);
let slice = self.temp(ty, test.span);
- self.cfg.push_assign(block, source_info, &slice,
- Rvalue::Cast(CastKind::Unsize, array, ty));
+ self.cfg.push_assign(
+ block, source_info, &slice, Rvalue::Cast(
+ CastKind::Pointer(PointerCast::Unsize), array, ty
+ )
+ );
expect = Operand::Move(slice);
}
},
use rustc::ty::{self, Ty, TypeAndMut};
use rustc::ty::layout::{self, TyLayout, Size};
+use rustc::ty::adjustment::{PointerCast};
use syntax::ast::{FloatTy, IntTy, UintTy};
use rustc_apfloat::ieee::{Single, Double};
) -> EvalResult<'tcx> {
use rustc::mir::CastKind::*;
match kind {
- Unsize => {
+ Pointer(PointerCast::Unsize) => {
self.unsize_into(src, dest)?;
}
- Misc | MutToConstPointer => {
+ Misc | Pointer(PointerCast::MutToConstPointer) => {
let src = self.read_immediate(src)?;
if self.type_is_fat_ptr(src.layout.ty) {
}
}
- ReifyFnPointer => {
+ Pointer(PointerCast::ReifyFnPointer) => {
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::FnDef(def_id, substs) => {
}
}
- UnsafeFnPointer => {
+ Pointer(PointerCast::UnsafeFnPointer) => {
let src = self.read_immediate(src)?;
match dest.layout.ty.sty {
ty::FnPtr(_) => {
}
}
- ClosureFnPointer(_) => {
+ Pointer(PointerCast::ClosureFnPointer(_)) => {
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::Closure(def_id, substs) => {
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
-use rustc::ty::adjustment::CustomCoerceUnsized;
+use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc::session::config::EntryFnType;
use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind};
use rustc::mir::visit::Visitor as MirVisitor;
// When doing an cast from a regular pointer to a fat pointer, we
// have to instantiate all methods of the trait being cast to, so we
// can build the appropriate vtable.
- mir::Rvalue::Cast(mir::CastKind::Unsize, ref operand, target_ty) => {
+ mir::Rvalue::Cast(
+ mir::CastKind::Pointer(PointerCast::Unsize), ref operand, target_ty
+ ) => {
let target_ty = self.tcx.subst_and_normalize_erasing_regions(
self.param_substs,
ty::ParamEnv::reveal_all(),
self.output);
}
}
- mir::Rvalue::Cast(mir::CastKind::ReifyFnPointer, ref operand, _) => {
+ mir::Rvalue::Cast(
+ mir::CastKind::Pointer(PointerCast::ReifyFnPointer), ref operand, _
+ ) => {
let fn_ty = operand.ty(self.mir, self.tcx);
let fn_ty = self.tcx.subst_and_normalize_erasing_regions(
self.param_substs,
);
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
}
- mir::Rvalue::Cast(mir::CastKind::ClosureFnPointer(_), ref operand, _) => {
+ mir::Rvalue::Cast(
+ mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)), ref operand, _
+ ) => {
let source_ty = operand.ty(self.mir, self.tcx);
let source_ty = self.tcx.subst_and_normalize_erasing_regions(
self.param_substs,
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::traits::{self, TraitEngine};
-use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
+use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, adjustment::{PointerCast}};
use rustc::ty::cast::CastTy;
use rustc::ty::query::Providers;
use rustc::mir::*;
Rvalue::UnaryOp(UnOp::Not, _) |
Rvalue::NullaryOp(NullOp::SizeOf, _) |
Rvalue::CheckedBinaryOp(..) |
- Rvalue::Cast(CastKind::ReifyFnPointer, ..) |
- Rvalue::Cast(CastKind::UnsafeFnPointer, ..) |
- Rvalue::Cast(CastKind::ClosureFnPointer(_), ..) |
- Rvalue::Cast(CastKind::Unsize, ..) |
- Rvalue::Cast(CastKind::MutToConstPointer, ..) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), ..) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), ..) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), ..) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), ..) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), ..) |
Rvalue::Discriminant(..) |
Rvalue::Len(_) |
Rvalue::Ref(..) |
use rustc::hir::def_id::DefId;
use rustc::hir;
use rustc::mir::*;
-use rustc::ty::{self, Predicate, TyCtxt};
+use rustc::ty::{self, Predicate, TyCtxt, adjustment::{PointerCast}};
use rustc_target::spec::abi;
use std::borrow::Cow;
use syntax_pos::Span;
_ => check_operand(tcx, mir, operand, span),
}
}
- Rvalue::Cast(CastKind::MutToConstPointer, operand, _) => {
+ Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _) => {
check_operand(tcx, mir, operand, span)
}
- Rvalue::Cast(CastKind::UnsafeFnPointer, _, _) |
- Rvalue::Cast(CastKind::ClosureFnPointer(_), _, _) |
- Rvalue::Cast(CastKind::ReifyFnPointer, _, _) => Err((
+ Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), _, _) |
+ Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), _, _) => Err((
span,
"function pointer casts are not allowed in const fn".into(),
)),
- Rvalue::Cast(CastKind::Unsize, _, _) => Err((
+ Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => Err((
span,
"unsizing casts are not allowed in const fn".into(),
)),