From: Ariel Ben-Yehuda Date: Thu, 11 Feb 2016 16:31:20 +0000 (+0200) Subject: make *mut T -> *const T a coercion X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;ds=sidebyside;h=76608c8e0a09687e485b8a1eb0b47156ac54a7f3;p=rust.git make *mut T -> *const T a coercion rather than being implicit quasi-subtyping. Nothing good can come out of quasi-subtyping. --- diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 9b315aa46e5..93cc158cd12 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -721,10 +721,11 @@ fn walk_adjustment(&mut self, expr: &hir::Expr) { if let Some(adjustment) = adj { match adjustment { adjustment::AdjustReifyFnPointer | - adjustment::AdjustUnsafeFnPointer => { + adjustment::AdjustUnsafeFnPointer | + adjustment::AdjustMutToConstPointer => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. - debug!("walk_adjustment(AdjustReifyFnPointer|AdjustUnsafeFnPointer)"); + debug!("walk_adjustment: trivial adjustment"); let cmt_unadjusted = return_if_err!(self.mc.cat_expr_unadjusted(expr)); self.delegate_consume(expr.id, expr.span, cmt_unadjusted); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c16997157bd..fef35764e1c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -430,6 +430,7 @@ pub fn cat_expr(&self, expr: &hir::Expr) -> McResult> { adjustment::AdjustReifyFnPointer | adjustment::AdjustUnsafeFnPointer | + adjustment::AdjustMutToConstPointer | adjustment::AdjustDerefRef(_) => { debug!("cat_expr({:?}): {:?}", adjustment, diff --git a/src/librustc/middle/ty/adjustment.rs b/src/librustc/middle/ty/adjustment.rs index 6cab0baa553..afe177fbdcd 100644 --- a/src/librustc/middle/ty/adjustment.rs +++ b/src/librustc/middle/ty/adjustment.rs @@ -21,8 +21,9 @@ #[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 + 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,7 +107,8 @@ impl<'tcx> AutoAdjustment<'tcx> { pub fn is_identity(&self) -> bool { match *self { AdjustReifyFnPointer | - AdjustUnsafeFnPointer => false, + AdjustUnsafeFnPointer | + AdjustMutToConstPointer => false, AdjustDerefRef(ref r) => r.is_identity(), } } @@ -151,7 +153,7 @@ pub fn adjust(&'tcx self, cx: &ty::ctxt<'tcx>, return match adjustment { Some(adjustment) => { match *adjustment { - AdjustReifyFnPointer => { + AdjustReifyFnPointer => { match self.sty { ty::TyBareFn(Some(_), b) => { cx.mk_fn(None, b) @@ -164,17 +166,32 @@ pub fn adjust(&'tcx self, cx: &ty::ctxt<'tcx>, } } - AdjustUnsafeFnPointer => { + AdjustUnsafeFnPointer => { match self.sty { ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b), ref b => { cx.sess.bug( - &format!("AdjustReifyFnPointer adjustment on non-fn-item: \ + &format!("AdjustUnsafeFnPointer adjustment on non-fn-ptr: \ {:?}", b)); } } - } + } + + AdjustMutToConstPointer => { + match self.sty { + ty::TyRawPtr(mt) => cx.mk_ptr(ty::TypeAndMut { + ty: mt.ty, + mutbl: hir::MutImmutable + }), + ref b => { + cx.sess.bug( + &format!("AdjustMutToConstPointer on non-raw-ptr: \ + {:?}", + b)); + } + } + } AdjustDerefRef(ref adj) => { let mut adjusted_ty = self; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a0939dc53df..5868f233776 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -396,6 +396,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ty::adjustment::AdjustUnsafeFnPointer => { write!(f, "AdjustUnsafeFnPointer") } + ty::adjustment::AdjustMutToConstPointer => { + write!(f, "AdjustMutToConstPointer") + } ty::adjustment::AdjustDerefRef(ref data) => { write!(f, "{:?}", data) } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 3a0bd3aa205..fe4df865a0e 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -610,7 +610,7 @@ fn emit_auto_adjustment<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, self.emit_enum("AutoAdjustment", |this| { match *adj { - adjustment::AdjustReifyFnPointer=> { + adjustment::AdjustReifyFnPointer => { this.emit_enum_variant("AdjustReifyFnPointer", 1, 0, |_| Ok(())) } @@ -620,8 +620,14 @@ fn emit_auto_adjustment<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, }) } + adjustment::AdjustMutToConstPointer => { + this.emit_enum_variant("AdjustMutToConstPointer", 3, 0, |_| { + Ok(()) + }) + } + adjustment::AdjustDerefRef(ref auto_deref_ref) => { - this.emit_enum_variant("AdjustDerefRef", 3, 2, |this| { + this.emit_enum_variant("AdjustDerefRef", 4, 2, |this| { this.emit_enum_variant_arg(0, |this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref))) }) @@ -1002,12 +1008,14 @@ fn read_upvar_capture(&mut self, dcx: &DecodeContext) -> ty::UpvarCapture { fn read_auto_adjustment<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> adjustment::AutoAdjustment<'tcx> { self.read_enum("AutoAdjustment", |this| { - let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer", "AdjustDerefRef"]; + let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer", + "AdjustMutToConstPointer", "AdjustDerefRef"]; this.read_enum_variant(&variants, |this, i| { Ok(match i { 1 => adjustment::AdjustReifyFnPointer, 2 => adjustment::AdjustUnsafeFnPointer, - 3 => { + 3 => adjustment::AdjustMutToConstPointer, + 4 => { let auto_deref_ref: adjustment::AutoDerefRef = this.read_enum_variant_arg(0, |this| Ok(this.read_auto_deref_ref(dcx))).unwrap(); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 769dbe0ab51..324c1e92efc 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -416,6 +416,9 @@ fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Expr<'tcx> { kind: kind, }; + debug!("unadjusted-expr={:?} applying adjustments={:?}", + expr, cx.tcx.tables.borrow().adjustments.get(&self.id)); + // Now apply adjustments, if any. match cx.tcx.tables.borrow().adjustments.get(&self.id) { None => {} @@ -437,6 +440,15 @@ fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Expr<'tcx> { kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() }, }; } + Some(&ty::adjustment::AdjustMutToConstPointer) => { + let adjusted_ty = cx.tcx.expr_ty_adjusted(self); + expr = Expr { + temp_lifetime: temp_lifetime, + ty: adjusted_ty, + span: self.span, + kind: ExprKind::Cast { source: expr.to_ref() }, + }; + } Some(&ty::adjustment::AdjustDerefRef(ref adj)) => { for i in 0..adj.autoderefs { let i = i as u32; diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index ee6003f713e..b0d459063ef 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -768,7 +768,8 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp match v.tcx.tables.borrow().adjustments.get(&e.id) { None | Some(&ty::adjustment::AdjustReifyFnPointer) | - Some(&ty::adjustment::AdjustUnsafeFnPointer) => {} + Some(&ty::adjustment::AdjustUnsafeFnPointer) | + Some(&ty::adjustment::AdjustMutToConstPointer) => {} Some(&ty::adjustment::AdjustDerefRef( ty::adjustment::AutoDerefRef { autoderefs, .. } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index e8c90fa31ea..79c73a83ee7 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -40,7 +40,7 @@ use trans::Disr; use middle::subst::Substs; use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer}; -use middle::ty::adjustment::AdjustUnsafeFnPointer; +use middle::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; use middle::ty::{self, Ty}; use middle::ty::cast::{CastTy,IntTy}; use util::nodemap::NodeMap; @@ -354,7 +354,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // FIXME(#19925) once fn item types are // zero-sized, we'll need to do something here } - Some(AdjustUnsafeFnPointer) => { + Some(AdjustUnsafeFnPointer) | Some(AdjustMutToConstPointer) => { // purely a type-level thing } Some(AdjustDerefRef(adj)) => { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index fac956c1ddd..782e38d3af2 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -71,7 +71,8 @@ use trans::type_of; use trans::Disr; use middle::ty::adjustment::{AdjustDerefRef, AdjustReifyFnPointer}; -use middle::ty::adjustment::{AdjustUnsafeFnPointer, CustomCoerceUnsized}; +use middle::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; +use middle::ty::adjustment::CustomCoerceUnsized; use middle::ty::{self, Ty}; use middle::ty::MethodCall; use middle::ty::cast::{CastKind, CastTy}; @@ -354,7 +355,7 @@ fn adjustment_required<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // zero-sized, we'll need to return true here false } - AdjustUnsafeFnPointer => { + AdjustUnsafeFnPointer | AdjustMutToConstPointer => { // purely a type-level thing false } @@ -391,7 +392,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // FIXME(#19925) once fn item types are // zero-sized, we'll need to do something here } - AdjustUnsafeFnPointer => { + AdjustUnsafeFnPointer | AdjustMutToConstPointer => { // purely a type-level thing } AdjustDerefRef(ref adj) => { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8f64e85de4b..f07464592fa 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -67,7 +67,7 @@ use middle::traits::{predicate_for_trait_def, report_selection_error}; use middle::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef}; use middle::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer}; -use middle::ty::adjustment::{AdjustUnsafeFnPointer}; +use middle::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; use middle::ty::{self, LvaluePreference, TypeAndMut, Ty}; use middle::ty::fold::TypeFoldable; use middle::ty::error::TypeError; @@ -427,6 +427,8 @@ fn coerce_unsafe_ptr(&self, autoref: Some(AutoUnsafe(mutbl_b)), unsize: None }))) + } else if mt_a.mutbl != mutbl_b { + Ok(Some(AdjustMutToConstPointer)) } else { Ok(None) } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index e663e449cfc..51353239790 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -305,6 +305,10 @@ fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) { adjustment::AdjustReifyFnPointer } + adjustment::AdjustMutToConstPointer => { + adjustment::AdjustMutToConstPointer + } + adjustment::AdjustUnsafeFnPointer => { adjustment::AdjustUnsafeFnPointer }