Auto merge of #59987 - saleemjaffer:refactor_adjust_castkinds, r=oli-obk
Refactor Adjust and CastKind fixes rust-lang#59588
This commit is contained in:
commit
72bc62047f
25 changed files with 161 additions and 219 deletions
|
|
@ -705,11 +705,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
|
||||
match adjustment.kind {
|
||||
adjustment::Adjust::NeverToAny |
|
||||
adjustment::Adjust::ReifyFnPointer |
|
||||
adjustment::Adjust::UnsafeFnPointer |
|
||||
adjustment::Adjust::ClosureFnPointer(_) |
|
||||
adjustment::Adjust::MutToConstPointer |
|
||||
adjustment::Adjust::Unsize => {
|
||||
adjustment::Adjust::Pointer(_) => {
|
||||
// Creating a closure/fn-pointer or unsizing consumes
|
||||
// the input and stores it into the resulting rvalue.
|
||||
self.delegate_consume(expr.hir_id, expr.span, &cmt);
|
||||
|
|
|
|||
|
|
@ -619,12 +619,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
adjustment::Adjust::NeverToAny |
|
||||
adjustment::Adjust::ReifyFnPointer |
|
||||
adjustment::Adjust::UnsafeFnPointer |
|
||||
adjustment::Adjust::ClosureFnPointer(_) |
|
||||
adjustment::Adjust::MutToConstPointer |
|
||||
adjustment::Adjust::Borrow(_) |
|
||||
adjustment::Adjust::Unsize => {
|
||||
adjustment::Adjust::Pointer(_) |
|
||||
adjustment::Adjust::Borrow(_) => {
|
||||
// Result is an rvalue.
|
||||
Ok(self.cat_rvalue_node(expr.hir_id, expr.span, target))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ use crate::ty::{
|
|||
UserTypeAnnotationIndex,
|
||||
};
|
||||
use crate::ty::print::{FmtPrinter, Printer};
|
||||
use crate::ty::adjustment::{PointerCast};
|
||||
|
||||
pub use crate::mir::interpret::AssertMessage;
|
||||
|
||||
|
|
@ -2342,29 +2343,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)]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,34 @@ use crate::ty::subst::SubstsRef;
|
|||
use rustc_macros::HashStable;
|
||||
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum PointerCast {
|
||||
/// Go from a fn-item type to a fn-pointer type.
|
||||
ReifyFnPointer,
|
||||
|
||||
/// Go from a safe fn pointer to an unsafe fn pointer.
|
||||
UnsafeFnPointer,
|
||||
|
||||
/// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
|
||||
/// It cannot convert a closure that requires unsafe.
|
||||
ClosureFnPointer(hir::Unsafety),
|
||||
|
||||
/// Go from a mut raw pointer to a const raw pointer.
|
||||
MutToConstPointer,
|
||||
|
||||
/// Unsize a pointer/reference value, e.g., `&[T; n]` to
|
||||
/// `&[T]`. Note that the source could be a thin or fat pointer.
|
||||
/// This will do things like convert thin pointers to fat
|
||||
/// pointers, or convert structs containing thin pointers to
|
||||
/// structs containing fat pointers, or convert between fat
|
||||
/// pointers. We don't store the details of how the transform is
|
||||
/// done (in fact, we don't know that, because it might depend on
|
||||
/// the precise type parameters). We just store the target
|
||||
/// type. Codegen backends and miri figure out what has to be done
|
||||
/// based on the precise source/target type at hand.
|
||||
Unsize,
|
||||
}
|
||||
|
||||
/// Represents coercing a value to a different type of value.
|
||||
///
|
||||
/// We transform values by following a number of `Adjust` steps in order.
|
||||
|
|
@ -56,36 +84,13 @@ pub enum Adjust<'tcx> {
|
|||
/// Go from ! to any type.
|
||||
NeverToAny,
|
||||
|
||||
/// Go from a fn-item type to a fn-pointer type.
|
||||
ReifyFnPointer,
|
||||
|
||||
/// Go from a safe fn pointer to an unsafe fn pointer.
|
||||
UnsafeFnPointer,
|
||||
|
||||
/// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
|
||||
/// It cannot convert a closure that requires unsafe.
|
||||
ClosureFnPointer(hir::Unsafety),
|
||||
|
||||
/// Go from a mut raw pointer to a const raw pointer.
|
||||
MutToConstPointer,
|
||||
|
||||
/// Dereference once, producing a place.
|
||||
Deref(Option<OverloadedDeref<'tcx>>),
|
||||
|
||||
/// Take the address and produce either a `&` or `*` pointer.
|
||||
Borrow(AutoBorrow<'tcx>),
|
||||
|
||||
/// Unsize a pointer/reference value, e.g., `&[T; n]` to
|
||||
/// `&[T]`. Note that the source could be a thin or fat pointer.
|
||||
/// This will do things like convert thin pointers to fat
|
||||
/// pointers, or convert structs containing thin pointers to
|
||||
/// structs containing fat pointers, or convert between fat
|
||||
/// pointers. We don't store the details of how the transform is
|
||||
/// done (in fact, we don't know that, because it might depend on
|
||||
/// the precise type parameters). We just store the target
|
||||
/// type. Codegen backends and miri figure out what has to be done
|
||||
/// based on the precise source/target type at hand.
|
||||
Unsize,
|
||||
Pointer(PointerCast),
|
||||
}
|
||||
|
||||
/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ CloneTypeFoldableAndLiftImpls! {
|
|||
crate::ty::IntVarValue,
|
||||
crate::ty::ParamConst,
|
||||
crate::ty::ParamTy,
|
||||
crate::ty::adjustment::PointerCast,
|
||||
crate::ty::RegionVid,
|
||||
crate::ty::UniverseIndex,
|
||||
crate::ty::Variance,
|
||||
|
|
@ -626,16 +627,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
|
|||
match *self {
|
||||
ty::adjustment::Adjust::NeverToAny =>
|
||||
Some(ty::adjustment::Adjust::NeverToAny),
|
||||
ty::adjustment::Adjust::ReifyFnPointer =>
|
||||
Some(ty::adjustment::Adjust::ReifyFnPointer),
|
||||
ty::adjustment::Adjust::UnsafeFnPointer =>
|
||||
Some(ty::adjustment::Adjust::UnsafeFnPointer),
|
||||
ty::adjustment::Adjust::ClosureFnPointer(unsafety) =>
|
||||
Some(ty::adjustment::Adjust::ClosureFnPointer(unsafety)),
|
||||
ty::adjustment::Adjust::MutToConstPointer =>
|
||||
Some(ty::adjustment::Adjust::MutToConstPointer),
|
||||
ty::adjustment::Adjust::Unsize =>
|
||||
Some(ty::adjustment::Adjust::Unsize),
|
||||
ty::adjustment::Adjust::Pointer(ptr) =>
|
||||
Some(ty::adjustment::Adjust::Pointer(ptr)),
|
||||
ty::adjustment::Adjust::Deref(ref overloaded) => {
|
||||
tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
|
||||
}
|
||||
|
|
@ -1185,11 +1178,7 @@ BraceStructTypeFoldableImpl! {
|
|||
EnumTypeFoldableImpl! {
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
|
||||
(ty::adjustment::Adjust::NeverToAny),
|
||||
(ty::adjustment::Adjust::ReifyFnPointer),
|
||||
(ty::adjustment::Adjust::UnsafeFnPointer),
|
||||
(ty::adjustment::Adjust::ClosureFnPointer)(a),
|
||||
(ty::adjustment::Adjust::MutToConstPointer),
|
||||
(ty::adjustment::Adjust::Unsize),
|
||||
(ty::adjustment::Adjust::Pointer)(a),
|
||||
(ty::adjustment::Adjust::Deref)(a),
|
||||
(ty::adjustment::Adjust::Borrow)(a),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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") {
|
||||
|
|
@ -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(
|
||||
|
|
@ -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) => {
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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 =>
|
||||
|
|
|
|||
|
|
@ -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::{
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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(),
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -193,11 +193,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
| ExprKind::Cast { .. }
|
||||
| ExprKind::Use { .. }
|
||||
| ExprKind::NeverToAny { .. }
|
||||
| ExprKind::ReifyFnPointer { .. }
|
||||
| ExprKind::ClosureFnPointer { .. }
|
||||
| ExprKind::UnsafeFnPointer { .. }
|
||||
| ExprKind::MutToConstPointer { .. }
|
||||
| ExprKind::Unsize { .. }
|
||||
| ExprKind::Pointer { .. }
|
||||
| ExprKind::Repeat { .. }
|
||||
| ExprKind::Borrow { .. }
|
||||
| ExprKind::If { .. }
|
||||
|
|
|
|||
|
|
@ -154,25 +154,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
let source = unpack!(block = this.as_operand(block, scope, source));
|
||||
block.and(Rvalue::Use(source))
|
||||
}
|
||||
ExprKind::ReifyFnPointer { source } => {
|
||||
ExprKind::Pointer { cast, source } => {
|
||||
let source = unpack!(block = this.as_operand(block, scope, source));
|
||||
block.and(Rvalue::Cast(CastKind::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))
|
||||
}
|
||||
ExprKind::ClosureFnPointer { source, unsafety } => {
|
||||
let source = unpack!(block = this.as_operand(block, scope, source));
|
||||
block.and(Rvalue::Cast(CastKind::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))
|
||||
}
|
||||
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(cast), source, expr.ty))
|
||||
}
|
||||
ExprKind::Array { fields } => {
|
||||
// (*) We would (maybe) be closer to codegen if we
|
||||
|
|
|
|||
|
|
@ -59,11 +59,7 @@ impl Category {
|
|||
| ExprKind::Box { .. }
|
||||
| ExprKind::Cast { .. }
|
||||
| ExprKind::Use { .. }
|
||||
| ExprKind::ReifyFnPointer { .. }
|
||||
| ExprKind::ClosureFnPointer { .. }
|
||||
| ExprKind::UnsafeFnPointer { .. }
|
||||
| ExprKind::MutToConstPointer { .. }
|
||||
| ExprKind::Unsize { .. }
|
||||
| ExprKind::Pointer { .. }
|
||||
| ExprKind::Repeat { .. }
|
||||
| ExprKind::Borrow { .. }
|
||||
| ExprKind::Assign { .. }
|
||||
|
|
|
|||
|
|
@ -380,11 +380,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
| ExprKind::Box { .. }
|
||||
| ExprKind::Cast { .. }
|
||||
| ExprKind::Use { .. }
|
||||
| ExprKind::ReifyFnPointer { .. }
|
||||
| ExprKind::ClosureFnPointer { .. }
|
||||
| ExprKind::UnsafeFnPointer { .. }
|
||||
| ExprKind::MutToConstPointer { .. }
|
||||
| ExprKind::Unsize { .. }
|
||||
| ExprKind::Pointer { .. }
|
||||
| ExprKind::Repeat { .. }
|
||||
| ExprKind::Borrow { .. }
|
||||
| ExprKind::Array { .. }
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
|
@ -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(
|
||||
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_data_structures::indexed_vec::Idx;
|
|||
use rustc::hir::def::{CtorOf, Def, CtorKind};
|
||||
use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
|
||||
use rustc::ty::{self, AdtKind, Ty};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
|
||||
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::LocalDefId;
|
||||
|
|
@ -74,45 +74,44 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
adjustment: &Adjustment<'tcx>)
|
||||
-> Expr<'tcx> {
|
||||
let Expr { temp_lifetime, mut span, .. } = expr;
|
||||
|
||||
// Adjust the span from the block, to the last expression of the
|
||||
// block. This is a better span when returning a mutable reference
|
||||
// with too short a lifetime. The error message will use the span
|
||||
// from the assignment to the return place, which should only point
|
||||
// at the returned value, not the entire function body.
|
||||
//
|
||||
// fn return_short_lived<'a>(x: &'a mut i32) -> &'static mut i32 {
|
||||
// x
|
||||
// // ^ error message points at this expression.
|
||||
// }
|
||||
let mut adjust_span = |expr: &mut Expr<'tcx>| {
|
||||
if let ExprKind::Block { body } = expr.kind {
|
||||
if let Some(ref last_expr) = body.expr {
|
||||
span = last_expr.span;
|
||||
expr.span = span;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let kind = match adjustment.kind {
|
||||
Adjust::ReifyFnPointer => {
|
||||
ExprKind::ReifyFnPointer { source: expr.to_ref() }
|
||||
Adjust::Pointer(PointerCast::Unsize) => {
|
||||
adjust_span(&mut expr);
|
||||
ExprKind::Pointer { cast: PointerCast::Unsize, source: expr.to_ref() }
|
||||
}
|
||||
Adjust::UnsafeFnPointer => {
|
||||
ExprKind::UnsafeFnPointer { source: expr.to_ref() }
|
||||
}
|
||||
Adjust::ClosureFnPointer(unsafety) => {
|
||||
ExprKind::ClosureFnPointer { source: expr.to_ref(), unsafety }
|
||||
Adjust::Pointer(cast) => {
|
||||
ExprKind::Pointer { cast, source: expr.to_ref() }
|
||||
}
|
||||
Adjust::NeverToAny => {
|
||||
ExprKind::NeverToAny { source: expr.to_ref() }
|
||||
}
|
||||
Adjust::MutToConstPointer => {
|
||||
ExprKind::MutToConstPointer { source: expr.to_ref() }
|
||||
}
|
||||
Adjust::Deref(None) => {
|
||||
// Adjust the span from the block, to the last expression of the
|
||||
// block. This is a better span when returning a mutable reference
|
||||
// with too short a lifetime. The error message will use the span
|
||||
// from the assignment to the return place, which should only point
|
||||
// at the returned value, not the entire function body.
|
||||
//
|
||||
// fn return_short_lived<'a>(x: &'a mut i32) -> &'static mut i32 {
|
||||
// x
|
||||
// // ^ error message points at this expression.
|
||||
// }
|
||||
//
|
||||
// We don't need to do this adjustment in the next match arm since
|
||||
// deref coercions always start with a built-in deref.
|
||||
if let ExprKind::Block { body } = expr.kind {
|
||||
if let Some(ref last_expr) = body.expr {
|
||||
span = last_expr.span;
|
||||
expr.span = span;
|
||||
}
|
||||
}
|
||||
adjust_span(&mut expr);
|
||||
ExprKind::Deref { arg: expr.to_ref() }
|
||||
}
|
||||
Adjust::Deref(Some(deref)) => {
|
||||
// We don't need to do call adjust_span here since
|
||||
// deref coercions always start with a built-in deref.
|
||||
let call = deref.method_call(cx.tcx(), expr.ty);
|
||||
|
||||
expr = Expr {
|
||||
|
|
@ -187,16 +186,6 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
// since they get rid of a borrow implicitly.
|
||||
ExprKind::Use { source: cast_expr.to_ref() }
|
||||
}
|
||||
Adjust::Unsize => {
|
||||
// See the above comment for Adjust::Deref
|
||||
if let ExprKind::Block { body } = expr.kind {
|
||||
if let Some(ref last_expr) = body.expr {
|
||||
span = last_expr.span;
|
||||
expr.span = span;
|
||||
}
|
||||
}
|
||||
ExprKind::Unsize { source: expr.to_ref() }
|
||||
}
|
||||
};
|
||||
|
||||
Expr {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use rustc::infer::canonical::Canonical;
|
|||
use rustc::middle::region;
|
||||
use rustc::ty::subst::SubstsRef;
|
||||
use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, UserType};
|
||||
use rustc::ty::adjustment::{PointerCast};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::hir;
|
||||
use syntax_pos::Span;
|
||||
|
|
@ -180,20 +181,8 @@ pub enum ExprKind<'tcx> {
|
|||
NeverToAny {
|
||||
source: ExprRef<'tcx>,
|
||||
},
|
||||
ReifyFnPointer {
|
||||
source: ExprRef<'tcx>,
|
||||
},
|
||||
ClosureFnPointer {
|
||||
source: ExprRef<'tcx>,
|
||||
unsafety: hir::Unsafety,
|
||||
},
|
||||
UnsafeFnPointer {
|
||||
source: ExprRef<'tcx>,
|
||||
},
|
||||
MutToConstPointer {
|
||||
source: ExprRef<'tcx>,
|
||||
},
|
||||
Unsize {
|
||||
Pointer {
|
||||
cast: PointerCast,
|
||||
source: ExprRef<'tcx>,
|
||||
},
|
||||
If {
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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) => {
|
||||
|
|
@ -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(_) => {
|
||||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -531,7 +531,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(),
|
||||
|
|
@ -556,7 +558,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,
|
||||
|
|
@ -565,7 +569,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,
|
||||
|
|
|
|||
|
|
@ -1108,11 +1108,7 @@ 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(_), ..) |
|
||||
Rvalue::Discriminant(..) |
|
||||
Rvalue::Len(_) |
|
||||
Rvalue::Ref(..) |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
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;
|
||||
|
|
@ -152,16 +152,16 @@ fn check_rvalue(
|
|||
_ => 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(),
|
||||
)),
|
||||
|
|
|
|||
|
|
@ -584,12 +584,8 @@ fn check_adjustments<'a, 'tcx>(
|
|||
while let Some(adjustment) = adjustments.next() {
|
||||
match adjustment.kind {
|
||||
Adjust::NeverToAny |
|
||||
Adjust::ReifyFnPointer |
|
||||
Adjust::UnsafeFnPointer |
|
||||
Adjust::ClosureFnPointer(_) |
|
||||
Adjust::MutToConstPointer |
|
||||
Adjust::Borrow(_) |
|
||||
Adjust::Unsize => {}
|
||||
Adjust::Pointer(_) |
|
||||
Adjust::Borrow(_) => {}
|
||||
|
||||
Adjust::Deref(_) => {
|
||||
if let Some(next_adjustment) = adjustments.peek() {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ use rustc::hir::def_id::DefId;
|
|||
use rustc::infer::{Coercion, InferResult, InferOk};
|
||||
use rustc::infer::type_variable::TypeVariableOrigin;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::adjustment::{
|
||||
Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
|
||||
};
|
||||
use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::error::TypeError;
|
||||
|
|
@ -512,7 +514,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
let coerce_target = self.next_ty_var(origin);
|
||||
let mut coercion = self.unify_and(coerce_target, target, |target| {
|
||||
let unsize = Adjustment {
|
||||
kind: Adjust::Unsize,
|
||||
kind: Adjust::Pointer(PointerCast::Unsize),
|
||||
target
|
||||
};
|
||||
match reborrow {
|
||||
|
|
@ -661,7 +663,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
debug!("coerce_from_fn_pointer(a={:?}, b={:?})", a, b);
|
||||
|
||||
self.coerce_from_safe_fn(a, fn_ty_a, b,
|
||||
simple(Adjust::UnsafeFnPointer), identity)
|
||||
simple(Adjust::Pointer(PointerCast::UnsafeFnPointer)), identity)
|
||||
}
|
||||
|
||||
fn coerce_from_fn_item(&self,
|
||||
|
|
@ -687,11 +689,17 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
b,
|
||||
|unsafe_ty| {
|
||||
vec![
|
||||
Adjustment { kind: Adjust::ReifyFnPointer, target: a_fn_pointer },
|
||||
Adjustment { kind: Adjust::UnsafeFnPointer, target: unsafe_ty },
|
||||
Adjustment {
|
||||
kind: Adjust::Pointer(PointerCast::ReifyFnPointer),
|
||||
target: a_fn_pointer
|
||||
},
|
||||
Adjustment {
|
||||
kind: Adjust::Pointer(PointerCast::UnsafeFnPointer),
|
||||
target: unsafe_ty
|
||||
},
|
||||
]
|
||||
},
|
||||
simple(Adjust::ReifyFnPointer)
|
||||
simple(Adjust::Pointer(PointerCast::ReifyFnPointer))
|
||||
)?;
|
||||
|
||||
obligations.extend(o2);
|
||||
|
|
@ -727,7 +735,9 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety);
|
||||
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})",
|
||||
a, b, pointer_ty);
|
||||
self.unify_and(pointer_ty, b, simple(Adjust::ClosureFnPointer(unsafety)))
|
||||
self.unify_and(pointer_ty, b, simple(
|
||||
Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety))
|
||||
))
|
||||
}
|
||||
_ => self.unify_and(a, b, identity),
|
||||
}
|
||||
|
|
@ -766,7 +776,9 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
}]
|
||||
})
|
||||
} else if mt_a.mutbl != mutbl_b {
|
||||
self.unify_and(a_unsafe, b, simple(Adjust::MutToConstPointer))
|
||||
self.unify_and(
|
||||
a_unsafe, b, simple(Adjust::Pointer(PointerCast::MutToConstPointer))
|
||||
)
|
||||
} else {
|
||||
self.unify_and(a_unsafe, b, identity)
|
||||
}
|
||||
|
|
@ -857,7 +869,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// The only adjustment that can produce an fn item is
|
||||
// `NeverToAny`, so this should always be valid.
|
||||
self.apply_adjustments(expr, vec![Adjustment {
|
||||
kind: Adjust::ReifyFnPointer,
|
||||
kind: Adjust::Pointer(PointerCast::ReifyFnPointer),
|
||||
target: fn_ptr
|
||||
}]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::hir::def_id::DefId;
|
|||
use rustc::ty::subst::{Subst, SubstsRef};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, GenericParamDefKind};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref, PointerCast};
|
||||
use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::infer::{self, InferOk};
|
||||
|
|
@ -179,7 +179,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
ty: unsize_target
|
||||
});
|
||||
adjustments.push(Adjustment {
|
||||
kind: Adjust::Unsize,
|
||||
kind: Adjust::Pointer(PointerCast::Unsize),
|
||||
target
|
||||
});
|
||||
}
|
||||
|
|
@ -565,7 +565,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
// If we have an autoref followed by unsizing at the end, fix the unsize target.
|
||||
match adjustments[..] {
|
||||
[.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
|
||||
Adjustment { kind: Adjust::Unsize, ref mut target }] => {
|
||||
Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), ref mut target }] => {
|
||||
*target = method.sig.inputs()[0];
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,9 @@ use rustc::ty::{
|
|||
self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility,
|
||||
ToPolyTraitRef, ToPredicate, RegionKind, UserType
|
||||
};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::adjustment::{
|
||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
|
||||
};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::subst::{UnpackedKind, Subst, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts};
|
||||
|
|
@ -2664,7 +2666,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
if unsize {
|
||||
adjustments.push(Adjustment {
|
||||
kind: Adjust::Unsize,
|
||||
kind: Adjust::Pointer(PointerCast::Unsize),
|
||||
target: method.sig.inputs()[0]
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc::hir;
|
|||
use rustc::hir::def_id::{DefId, DefIndex};
|
||||
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
|
||||
use rustc::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
|
||||
use rustc::ty::subst::UnpackedKind;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
|
@ -197,7 +197,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
// Since this is "after" the other adjustment to be
|
||||
// discarded, we do an extra `pop()`
|
||||
Some(Adjustment {
|
||||
kind: Adjust::Unsize,
|
||||
kind: Adjust::Pointer(PointerCast::Unsize),
|
||||
..
|
||||
}) => {
|
||||
// So the borrow discard actually happens here
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ fn main() {
|
|||
// _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48];
|
||||
// _5 = &_6;
|
||||
// _4 = &(*_5);
|
||||
// _3 = move _4 as &'static [(u32, u32)] (Unsize);
|
||||
// _3 = move _4 as &'static [(u32, u32)] (Pointer(Unsize));
|
||||
// _2 = Foo { tup: const "hi", data: move _3 };
|
||||
// _1 = &_2;
|
||||
// _0 = &(*_1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue