Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::ty::{
UserTypeAnnotationIndex,
};
use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::adjustment::{PointerCast};

pub use crate::mir::interpret::AssertMessage;

Expand Down Expand Up @@ -2248,29 +2249,11 @@ pub enum Rvalue<'tcx> {
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)]
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/ty/adjustment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ use crate::ty::subst::SubstsRef;
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.
Expand Down
16 changes: 8 additions & 8 deletions src/librustc_codegen_ssa/mir/rvalue.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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;
Expand Down Expand Up @@ -37,7 +37,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
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) {
Expand Down Expand Up @@ -178,7 +178,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
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") {
Expand All @@ -193,7 +193,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::CastKind::ClosureFnPointer(_) => {
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => {
match operand.layout.ty.sty {
ty::Closure(def_id, substs) => {
let instance = monomorphize::resolve_closure(
Expand All @@ -205,11 +205,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
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) => {
Expand All @@ -236,7 +236,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
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) {
Expand All @@ -254,7 +254,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
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);
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc::mir::{
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;
Expand Down Expand Up @@ -580,7 +581,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
},
// 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 =>
Expand Down
11 changes: 6 additions & 5 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use rustc::traits::query::type_op;
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::{
Expand Down Expand Up @@ -1972,7 +1973,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {

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
Expand Down Expand Up @@ -2001,7 +2002,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}

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)
Expand All @@ -2027,7 +2028,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, '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
Expand Down Expand Up @@ -2056,7 +2057,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}

CastKind::Unsize => {
CastKind::Pointer(PointerCast::Unsize) => {
let &ty = ty;
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
Expand All @@ -2070,7 +2071,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
);
}

CastKind::MutToConstPointer => {
CastKind::Pointer(PointerCast::MutToConstPointer) => {
let ty_from = match op.ty(mir, tcx).sty {
ty::RawPtr(ty::TypeAndMut {
ty: ty_from,
Expand Down
21 changes: 16 additions & 5 deletions src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc::middle::region;
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> {
Expand Down Expand Up @@ -156,23 +157,33 @@ 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
Expand Down
16 changes: 11 additions & 5 deletions src/librustc_mir/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::hair::*;
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::*;
Expand Down Expand Up @@ -280,8 +280,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
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(
Expand All @@ -291,8 +294,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
);

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);
}
},
Expand Down
11 changes: 6 additions & 5 deletions src/librustc_mir/interpret/cast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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};
Expand Down Expand Up @@ -29,11 +30,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
) -> 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) {
Expand Down Expand Up @@ -72,7 +73,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
}
}

ReifyFnPointer => {
Pointer(PointerCast::ReifyFnPointer) => {
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::FnDef(def_id, substs) => {
Expand All @@ -93,7 +94,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
}
}

UnsafeFnPointer => {
Pointer(PointerCast::UnsafeFnPointer) => {
let src = self.read_immediate(src)?;
match dest.layout.ty.sty {
ty::FnPtr(_) => {
Expand All @@ -104,7 +105,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
}
}

ClosureFnPointer(_) => {
Pointer(PointerCast::ClosureFnPointer(_)) => {
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::Closure(def_id, substs) => {
Expand Down
14 changes: 10 additions & 4 deletions src/librustc_mir/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue};
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;
Expand Down Expand Up @@ -529,7 +529,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
// 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(),
Expand All @@ -554,7 +556,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
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,
Expand All @@ -563,7 +567,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
);
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,
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_target::spec::abi::Abi;
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::*;
Expand Down Expand Up @@ -1106,11 +1106,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
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(..) |
Expand Down
Loading