Skip to content

Refactor Adjust and CastKind #59987

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 1 addition & 5 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 2 additions & 6 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
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
53 changes: 29 additions & 24 deletions src/librustc/ty/adjustment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)`
Expand Down
19 changes: 4 additions & 15 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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),
}
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
6 changes: 1 addition & 5 deletions src/librustc_mir/build/expr/as_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 { .. }
Expand Down
20 changes: 2 additions & 18 deletions src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 1 addition & 5 deletions src/librustc_mir/build/expr/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 { .. }
Expand Down
6 changes: 1 addition & 5 deletions src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 { .. }
Expand Down
Loading