From 5be6b0beb9a68af64c0851409fde9f6aee5d0ecf Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 15 Apr 2019 19:20:44 +0530 Subject: [PATCH 1/6] basic refactor. Adding PointerCast enum --- src/librustc/mir/mod.rs | 23 +++---------------- src/librustc/ty/adjustment.rs | 9 ++++++++ src/librustc_codegen_ssa/mir/rvalue.rs | 16 ++++++------- .../borrow_check/nll/explain_borrow/mod.rs | 5 +++- .../borrow_check/nll/type_check/mod.rs | 11 +++++---- src/librustc_mir/build/expr/as_rvalue.rs | 21 +++++++++++++---- src/librustc_mir/build/matches/test.rs | 16 +++++++++---- src/librustc_mir/interpret/cast.rs | 11 +++++---- src/librustc_mir/monomorphize/collector.rs | 14 +++++++---- src/librustc_mir/transform/qualify_consts.rs | 12 +++++----- .../transform/qualify_min_const_fn.rs | 12 +++++----- 11 files changed, 85 insertions(+), 65 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 8424c096e88c0..22c0f0e5c3945 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -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; @@ -2248,29 +2249,11 @@ pub enum Rvalue<'tcx> { Aggregate(Box>, Vec>), } + #[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` to a `Box` - /// (presuming `T: Trait`). - Unsize, + Pointer(PointerCast), } #[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index c2ef08c4c40fe..7b81f7c697909 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -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. diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 53640284a2ca9..35e9d918aa6f9 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -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); diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index e30938bc32659..5ad54080c5a61 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -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 => diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index ec5637d17072d..d123f3e405936 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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, diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 7289dd96edb8d..565524247174f 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -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> { @@ -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 diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index b06022196106a..1eaf3d7ba9982 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -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); } }, diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 5056d79bec4b1..32f218d49cea2 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -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) => { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index af875c2f9e8a1..2f4b3fa6ca8f7 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -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; @@ -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(), @@ -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, @@ -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, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 1faa9ad0d0da4..111f544399620 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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::*; @@ -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(..) | diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 87459571b529c..201dac1524e4d 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -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(), )), From 6321a323cc4af032b7e34c1b09a71eefdb369ac4 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 16 Apr 2019 13:40:04 +0530 Subject: [PATCH 2/6] refactor Adjustment to use new PointerCast enum --- src/librustc/middle/expr_use_visitor.rs | 6 +-- src/librustc/middle/mem_categorization.rs | 8 +--- src/librustc/ty/adjustment.rs | 44 +++++++++----------- src/librustc/ty/structural_impls.rs | 37 +++++++++------- src/librustc_mir/hair/cx/expr.rs | 12 +++--- src/librustc_mir/transform/qualify_consts.rs | 8 +--- src/librustc_passes/rvalue_promotion.rs | 8 +--- src/librustc_typeck/check/coercion.rs | 30 +++++++++---- src/librustc_typeck/check/method/confirm.rs | 6 +-- src/librustc_typeck/check/mod.rs | 6 ++- src/librustc_typeck/check/writeback.rs | 4 +- 11 files changed, 85 insertions(+), 84 deletions(-) diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 4f630fe9a3911..8fffef1c64eb8 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 1a3fef18404e3..b3683f8e65acc 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -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)) } diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 7b81f7c697909..0843a3a55fc41 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -7,10 +7,29 @@ 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, } @@ -65,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>), /// 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)` diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 262dc30033472..fe7ea775fdff6 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -7,6 +7,7 @@ use crate::hir::def::Namespace; use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid}; +use crate::ty::adjustment::{PointerCast}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -626,16 +627,16 @@ 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(PointerCast::ReifyFnPointer) => + Some(ty::adjustment::Adjust::Pointer(PointerCast::ReifyFnPointer)), + ty::adjustment::Adjust::Pointer(PointerCast::UnsafeFnPointer) => + Some(ty::adjustment::Adjust::Pointer(PointerCast::UnsafeFnPointer)), + ty::adjustment::Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety)) => + Some(ty::adjustment::Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety))), + ty::adjustment::Adjust::Pointer(PointerCast::MutToConstPointer) => + Some(ty::adjustment::Adjust::Pointer(PointerCast::MutToConstPointer)), + ty::adjustment::Adjust::Pointer(PointerCast::Unsize) => + Some(ty::adjustment::Adjust::Pointer(PointerCast::Unsize)), ty::adjustment::Adjust::Deref(ref overloaded) => { tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref) } @@ -1185,16 +1186,22 @@ 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), } } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::PointerCast { + (ty::adjustment::PointerCast::ReifyFnPointer), + (ty::adjustment::PointerCast::UnsafeFnPointer), + (ty::adjustment::PointerCast::ClosureFnPointer)(a), + (ty::adjustment::PointerCast::MutToConstPointer), + (ty::adjustment::PointerCast::Unsize), + } +} + BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> { region, mutbl, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 91113dc2271be..2133cd26e13ac 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -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; @@ -75,19 +75,19 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> Expr<'tcx> { let Expr { temp_lifetime, mut span, .. } = expr; let kind = match adjustment.kind { - Adjust::ReifyFnPointer => { + Adjust::Pointer(PointerCast::ReifyFnPointer) => { ExprKind::ReifyFnPointer { source: expr.to_ref() } } - Adjust::UnsafeFnPointer => { + Adjust::Pointer(PointerCast::UnsafeFnPointer) => { ExprKind::UnsafeFnPointer { source: expr.to_ref() } } - Adjust::ClosureFnPointer(unsafety) => { + Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety)) => { ExprKind::ClosureFnPointer { source: expr.to_ref(), unsafety } } Adjust::NeverToAny => { ExprKind::NeverToAny { source: expr.to_ref() } } - Adjust::MutToConstPointer => { + Adjust::Pointer(PointerCast::MutToConstPointer) => { ExprKind::MutToConstPointer { source: expr.to_ref() } } Adjust::Deref(None) => { @@ -187,7 +187,7 @@ 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 => { + Adjust::Pointer(PointerCast::Unsize) => { // See the above comment for Adjust::Deref if let ExprKind::Block { body } = expr.kind { if let Some(ref last_expr) = body.expr { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 111f544399620..3e34524b55644 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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, adjustment::{PointerCast}}; +use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::cast::CastTy; use rustc::ty::query::Providers; use rustc::mir::*; @@ -1106,11 +1106,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { Rvalue::UnaryOp(UnOp::Not, _) | Rvalue::NullaryOp(NullOp::SizeOf, _) | Rvalue::CheckedBinaryOp(..) | - 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::Cast(CastKind::Pointer(_), ..) | Rvalue::Discriminant(..) | Rvalue::Len(_) | Rvalue::Ref(..) | diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 7c37c38f2d741..ba60fdc027312 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -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() { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index c470bc09e8cd0..85eb0f9d49966 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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 }]); } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index e0b96ae884f3a..f93d5449e8b78 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -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]; } _ => {} diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 313ed19b945d1..748e3d643a1e9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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] }); } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index c2404917fa7a7..d9df4672f1478 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -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 From 63b476455674571402596edc13bff887732b51a5 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 16 Apr 2019 17:36:41 +0530 Subject: [PATCH 3/6] refactor ExprKind to use new PointerCast enum --- src/librustc/ty/structural_impls.rs | 24 +++--------------- src/librustc_mir/build/expr/as_place.rs | 6 +---- src/librustc_mir/build/expr/as_rvalue.rs | 31 ++---------------------- src/librustc_mir/build/expr/category.rs | 6 +---- src/librustc_mir/build/expr/into.rs | 6 +---- src/librustc_mir/hair/cx/expr.rs | 30 ++++++++--------------- src/librustc_mir/hair/mod.rs | 17 +++---------- 7 files changed, 21 insertions(+), 99 deletions(-) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index fe7ea775fdff6..9aaff33e93339 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -7,7 +7,6 @@ use crate::hir::def::Namespace; use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid}; -use crate::ty::adjustment::{PointerCast}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -327,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, @@ -627,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::Pointer(PointerCast::ReifyFnPointer) => - Some(ty::adjustment::Adjust::Pointer(PointerCast::ReifyFnPointer)), - ty::adjustment::Adjust::Pointer(PointerCast::UnsafeFnPointer) => - Some(ty::adjustment::Adjust::Pointer(PointerCast::UnsafeFnPointer)), - ty::adjustment::Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety)) => - Some(ty::adjustment::Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety))), - ty::adjustment::Adjust::Pointer(PointerCast::MutToConstPointer) => - Some(ty::adjustment::Adjust::Pointer(PointerCast::MutToConstPointer)), - ty::adjustment::Adjust::Pointer(PointerCast::Unsize) => - Some(ty::adjustment::Adjust::Pointer(PointerCast::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) } @@ -1192,16 +1184,6 @@ EnumTypeFoldableImpl! { } } -EnumTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::PointerCast { - (ty::adjustment::PointerCast::ReifyFnPointer), - (ty::adjustment::PointerCast::UnsafeFnPointer), - (ty::adjustment::PointerCast::ClosureFnPointer)(a), - (ty::adjustment::PointerCast::MutToConstPointer), - (ty::adjustment::PointerCast::Unsize), - } -} - BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> { region, mutbl, diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index f7cf09020138c..b500060684f81 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -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 { .. } diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 565524247174f..b9fec22da63ca 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -10,7 +10,6 @@ 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> { @@ -155,35 +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::Pointer(PointerCast::ReifyFnPointer), source, expr.ty) - ) - } - ExprKind::UnsafeFnPointer { source } => { - let source = unpack!(block = this.as_operand(block, scope, source)); - 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::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::Pointer(PointerCast::MutToConstPointer), source, expr.ty) - ) - } - ExprKind::Unsize { source } => { - let source = unpack!(block = this.as_operand(block, scope, source)); - block.and(Rvalue::Cast( - CastKind::Pointer(PointerCast::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 diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index c8c30ac3ce4d0..52f1d0eca5e3c 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -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 { .. } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 4d0418beea4dd..8967572ea8f64 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -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 { .. } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 2133cd26e13ac..28fedd9d25618 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -75,21 +75,21 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> Expr<'tcx> { let Expr { temp_lifetime, mut span, .. } = expr; let kind = match adjustment.kind { - Adjust::Pointer(PointerCast::ReifyFnPointer) => { - ExprKind::ReifyFnPointer { source: expr.to_ref() } - } - Adjust::Pointer(PointerCast::UnsafeFnPointer) => { - ExprKind::UnsafeFnPointer { source: expr.to_ref() } + Adjust::Pointer(PointerCast::Unsize) => { + if let ExprKind::Block { body } = expr.kind { + if let Some(ref last_expr) = body.expr { + span = last_expr.span; + expr.span = span; + } + } + ExprKind::Pointer { cast: PointerCast::Unsize, source: expr.to_ref() } } - Adjust::Pointer(PointerCast::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::Pointer(PointerCast::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 @@ -187,16 +187,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::Pointer(PointerCast::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 { diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index a661649db0fd4..2e53bee3f3d7f 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -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 { From d0c0815f013dc3cbd166dbd66557ed8cabd5611c Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 16 Apr 2019 19:29:45 +0530 Subject: [PATCH 4/6] fixing tests --- src/test/mir-opt/storage_live_dead_in_statics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs index e8ef1d9d3c38b..10f00cf8b0c32 100644 --- a/src/test/mir-opt/storage_live_dead_in_statics.rs +++ b/src/test/mir-opt/storage_live_dead_in_statics.rs @@ -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); From 999ee0190fbcabf13253d6f95bb7ab73709c9240 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 17 Apr 2019 17:58:33 +0530 Subject: [PATCH 5/6] code review fixes --- src/librustc_mir/hair/cx/expr.rs | 49 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 28fedd9d25618..bd17080e8c2a1 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -68,6 +68,26 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::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. +/// } +fn adjust_span<'tcx>(expr: &mut Expr<'tcx>) -> Span { + if let ExprKind::Block { body } = expr.kind { + if let Some(ref last_expr) = body.expr { + expr.span = last_expr.span; + } + } + + expr.span +} + fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir_expr: &'tcx hir::Expr, mut expr: Expr<'tcx>, @@ -76,12 +96,7 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let Expr { temp_lifetime, mut span, .. } = expr; let kind = match adjustment.kind { Adjust::Pointer(PointerCast::Unsize) => { - if let ExprKind::Block { body } = expr.kind { - if let Some(ref last_expr) = body.expr { - span = last_expr.span; - expr.span = span; - } - } + span = adjust_span(&mut expr); ExprKind::Pointer { cast: PointerCast::Unsize, source: expr.to_ref() } } Adjust::Pointer(cast) => { @@ -91,28 +106,12 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::NeverToAny { 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; - } - } + 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 { From a2f8269d0c2cdf05aa86d6ef478073f6f634d838 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Thu, 18 Apr 2019 00:10:45 +0530 Subject: [PATCH 6/6] making adjust_span a closure --- src/librustc_mir/hair/cx/expr.rs | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index bd17080e8c2a1..7ffdad08453e7 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -68,35 +68,35 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::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. -/// } -fn adjust_span<'tcx>(expr: &mut Expr<'tcx>) -> Span { - if let ExprKind::Block { body } = expr.kind { - if let Some(ref last_expr) = body.expr { - expr.span = last_expr.span; - } - } - - expr.span -} - fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir_expr: &'tcx hir::Expr, mut expr: Expr<'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::Pointer(PointerCast::Unsize) => { - span = adjust_span(&mut expr); + adjust_span(&mut expr); ExprKind::Pointer { cast: PointerCast::Unsize, source: expr.to_ref() } } Adjust::Pointer(cast) => { @@ -106,7 +106,7 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::NeverToAny { source: expr.to_ref() } } Adjust::Deref(None) => { - span = adjust_span(&mut expr); + adjust_span(&mut expr); ExprKind::Deref { arg: expr.to_ref() } } Adjust::Deref(Some(deref)) => {