diff options
| author | Andrew Cann <shum@canndrew.org> | 2016-06-25 18:42:52 +0800 |
|---|---|---|
| committer | Andrew Cann <shum@canndrew.org> | 2016-08-13 21:37:09 +0800 |
| commit | 0d863616e0a9c554b4da2e4373bdb5f1a98aa02d (patch) | |
| tree | 8ed23eb359b00b532e8157c3737ccd82ca40eb0f | |
| parent | b0a9acd783aec3449f5d8d772bc1bd4e59276cc8 (diff) | |
Add EmptyToAny adjustment
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 1 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 1 | ||||
| -rw-r--r-- | src/librustc/ty/adjustment.rs | 15 | ||||
| -rw-r--r-- | src/librustc/util/ppaux.rs | 3 | ||||
| -rw-r--r-- | src/librustc_metadata/astencode.rs | 16 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/as_lvalue.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/as_rvalue.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/category.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/into.rs | 8 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/expr.rs | 9 | ||||
| -rw-r--r-- | src/librustc_mir/hair/mod.rs | 3 | ||||
| -rw-r--r-- | src/librustc_passes/consts.rs | 1 | ||||
| -rw-r--r-- | src/librustc_trans/consts.rs | 3 | ||||
| -rw-r--r-- | src/librustc_trans/expr.rs | 9 | ||||
| -rw-r--r-- | src/librustc_typeck/check/writeback.rs | 4 |
15 files changed, 69 insertions, 7 deletions
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 18b80a9636b..4980b3abc63 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -717,6 +717,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let adj = infcx.adjustments().get(&expr.id).map(|x| x.clone()); if let Some(adjustment) = adj { match adjustment { + adjustment::AdjustEmptyToAny(..) | adjustment::AdjustReifyFnPointer | adjustment::AdjustUnsafeFnPointer | adjustment::AdjustMutToConstPointer => { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 0bc3c1ae899..9589687cf26 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -451,6 +451,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { self.cat_expr_autoderefd(expr, autoderefs) } + adjustment::AdjustEmptyToAny(..) | adjustment::AdjustReifyFnPointer | adjustment::AdjustUnsafeFnPointer | adjustment::AdjustMutToConstPointer | diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 47ca7d335ab..95b3a8bd42e 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -11,7 +11,7 @@ pub use self::AutoAdjustment::*; pub use self::AutoRef::*; -use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFoldable}; +use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeVariants}; use ty::LvaluePreference::{NoPreference}; use syntax::ast; @@ -21,9 +21,10 @@ use hir; #[derive(Copy, Clone)] pub enum AutoAdjustment<'tcx> { - AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type - AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer - AdjustMutToConstPointer, // go from a mut raw pointer to a const raw pointer + AdjustEmptyToAny(Ty<'tcx>), // go from ! to any type + AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type + AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer + AdjustMutToConstPointer, // go from a mut raw pointer to a const raw pointer AdjustDerefRef(AutoDerefRef<'tcx>), } @@ -106,6 +107,10 @@ pub struct AutoDerefRef<'tcx> { impl<'tcx> AutoAdjustment<'tcx> { pub fn is_identity(&self) -> bool { match *self { + AdjustEmptyToAny(ref ty) => match ty.sty { + TypeVariants::TyEmpty => true, + _ => false, + }, AdjustReifyFnPointer | AdjustUnsafeFnPointer | AdjustMutToConstPointer => false, @@ -154,6 +159,8 @@ impl<'a, 'gcx, 'tcx> ty::TyS<'tcx> { return match adjustment { Some(adjustment) => { match *adjustment { + AdjustEmptyToAny(ref ty) => ty, + AdjustReifyFnPointer => { match self.sty { ty::TyFnDef(_, _, f) => tcx.mk_fn_ptr(f), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fa1d1e0a901..b7851f9879d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -429,6 +429,9 @@ impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> { impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { + ty::adjustment::AdjustEmptyToAny(ref target) => { + write!(f, "AdjustEmptyToAny({:?})", target) + } ty::adjustment::AdjustReifyFnPointer => { write!(f, "AdjustReifyFnPointer") } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index f03c432c091..99d5758076f 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -644,6 +644,12 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { |this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref))) }) } + + adjustment::AdjustEmptyToAny(ref ty) => { + this.emit_enum_variant("AdjustEmptyToAny", 5, 1, |this| { + this.emit_enum_variant_arg(0, |this| Ok(this.emit_ty(ecx, ty))) + }) + } } }); } @@ -1017,7 +1023,8 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { -> adjustment::AutoAdjustment<'tcx> { self.read_enum("AutoAdjustment", |this| { let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer", - "AdjustMutToConstPointer", "AdjustDerefRef"]; + "AdjustMutToConstPointer", "AdjustDerefRef", + "AdjustEmptyToAny"]; this.read_enum_variant(&variants, |this, i| { Ok(match i { 1 => adjustment::AdjustReifyFnPointer, @@ -1030,6 +1037,13 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { adjustment::AdjustDerefRef(auto_deref_ref) } + 5 => { + let ty: Ty<'tcx> = this.read_enum_variant_arg(0, |this| { + Ok(this.read_ty(dcx)) + }).unwrap(); + + adjustment::AdjustEmptyToAny(ty) + } _ => bug!("bad enum variant for adjustment::AutoAdjustment") }) }) diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index dd6c9c02f56..420147d037c 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -96,6 +96,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::LogicalOp { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::EmptyToAny { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | ExprKind::Unsize { .. } | diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index f1487992cb5..5cf00a195dc 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -219,6 +219,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Block { .. } | ExprKind::Match { .. } | ExprKind::If { .. } | + ExprKind::EmptyToAny { .. } | ExprKind::Loop { .. } | ExprKind::LogicalOp { .. } | ExprKind::Call { .. } | diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 658b7779b44..fb5be8e7d1c 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -56,6 +56,7 @@ impl Category { ExprKind::LogicalOp { .. } | ExprKind::If { .. } | ExprKind::Match { .. } | + ExprKind::EmptyToAny { .. } | ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)), diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index fd9ddc05ab5..2610dc71ef4 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -45,6 +45,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Match { discriminant, arms } => { this.match_expr(destination, expr_span, block, discriminant, arms) } + ExprKind::EmptyToAny { source } => { + // TODO(canndrew): Do we need to do this? + unpack!(block = this.as_rvalue(block, source)); + + this.cfg.terminate(block, source_info, TerminatorKind::Unreachable); + let end_block = this.cfg.start_new_block(); + end_block.unit() + } ExprKind::If { condition: cond_expr, then: then_expr, otherwise: else_expr } => { let operand = unpack!(block = this.as_operand(block, cond_expr)); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 88fb65d8eea..28a23e2a499 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -60,6 +60,15 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() }, }; } + Some(&ty::adjustment::AdjustEmptyToAny(..)) => { + let adjusted_ty = cx.tcx.expr_ty_adjusted(self); + expr = Expr { + temp_lifetime: temp_lifetime, + ty: adjusted_ty, + span: self.span, + kind: ExprKind::EmptyToAny { source: expr.to_ref() }, + }; + } Some(&ty::adjustment::AdjustMutToConstPointer) => { let adjusted_ty = cx.tcx.expr_ty_adjusted(self); expr = Expr { diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index a2746bf30c9..14c3f0e580d 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -139,6 +139,9 @@ pub enum ExprKind<'tcx> { Cast { source: ExprRef<'tcx>, }, + EmptyToAny { + source: ExprRef<'tcx>, + }, ReifyFnPointer { source: ExprRef<'tcx>, }, diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 37e42cdea1b..9cd955b1caf 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -632,6 +632,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) { match v.tcx.tables.borrow().adjustments.get(&e.id) { None | + Some(&ty::adjustment::AdjustEmptyToAny(..)) | Some(&ty::adjustment::AdjustReifyFnPointer) | Some(&ty::adjustment::AdjustUnsafeFnPointer) | Some(&ty::adjustment::AdjustMutToConstPointer) => {} diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 769dd008af8..95af6db0260 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -34,7 +34,7 @@ use type_of; use value::Value; use Disr; use rustc::ty::subst::Substs; -use rustc::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer}; +use rustc::ty::adjustment::{AdjustEmptyToAny, AdjustDerefRef, AdjustReifyFnPointer}; use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::cast::{CastTy,IntTy}; @@ -348,6 +348,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, &cx.tcx().expr_ty_adjusted(e)); let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned(); match opt_adj { + Some(AdjustEmptyToAny(..)) => span_bug!(e.span, "const expression of type ! encountered"), Some(AdjustReifyFnPointer) => { match ety.sty { ty::TyFnDef(def_id, substs, _) => { diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index 2a60dd17446..eed543aa31c 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -69,7 +69,7 @@ use tvec; use type_of; use value::Value; use Disr; -use rustc::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer}; +use rustc::ty::adjustment::{AdjustEmptyToAny, AdjustDerefRef, AdjustReifyFnPointer}; use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::ty::{self, Ty, TyCtxt}; @@ -348,6 +348,7 @@ fn adjustment_required<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } match adjustment { + AdjustEmptyToAny(..) => true, AdjustReifyFnPointer => true, AdjustUnsafeFnPointer | AdjustMutToConstPointer => { // purely a type-level thing @@ -380,6 +381,12 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("unadjusted datum for expr {:?}: {:?} adjustment={:?}", expr, datum, adjustment); match adjustment { + AdjustEmptyToAny(..) => { + let const_ty = expr_ty(bcx, expr); + let llty = type_of::type_of(bcx.ccx(), const_ty); + let dummy = C_undef(llty.ptr_to()); + datum = Datum::new(dummy, const_ty, Rvalue::new(ByRef)).to_expr_datum(); + } AdjustReifyFnPointer => { match datum.ty.sty { ty::TyFnDef(def_id, substs, _) => { diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 9026920e7f4..5fe9b8742d7 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -378,6 +378,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { Some(adjustment) => { let resolved_adjustment = match adjustment { + adjustment::AdjustEmptyToAny(ty) => { + adjustment::AdjustEmptyToAny(self.resolve(&ty, reason)) + } + adjustment::AdjustReifyFnPointer => { adjustment::AdjustReifyFnPointer } |
