about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2016-02-11 18:31:20 +0200
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2016-02-20 01:54:58 +0200
commit76608c8e0a09687e485b8a1eb0b47156ac54a7f3 (patch)
tree94eb418ca25061d089871bdacc4db32175354d3f
parent6f633ef128335e11e9903f647c6a6150f3a714d1 (diff)
downloadrust-76608c8e0a09687e485b8a1eb0b47156ac54a7f3.tar.gz
rust-76608c8e0a09687e485b8a1eb0b47156ac54a7f3.zip
make *mut T -> *const T a coercion
rather than being implicit quasi-subtyping. Nothing good can come out
of quasi-subtyping.
-rw-r--r--src/librustc/middle/expr_use_visitor.rs5
-rw-r--r--src/librustc/middle/mem_categorization.rs1
-rw-r--r--src/librustc/middle/ty/adjustment.rs31
-rw-r--r--src/librustc/util/ppaux.rs3
-rw-r--r--src/librustc_metadata/astencode.rs16
-rw-r--r--src/librustc_mir/hair/cx/expr.rs12
-rw-r--r--src/librustc_passes/consts.rs3
-rw-r--r--src/librustc_trans/trans/consts.rs4
-rw-r--r--src/librustc_trans/trans/expr.rs7
-rw-r--r--src/librustc_typeck/check/coercion.rs4
-rw-r--r--src/librustc_typeck/check/writeback.rs4
11 files changed, 70 insertions, 20 deletions
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 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         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 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
 
                     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 @@ use rustc_front::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
+    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 @@ impl<'tcx> ty::TyS<'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 @@ impl<'tcx> ty::TyS<'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 @@ impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
             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 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
 
         self.emit_enum("AutoAdjustment", |this| {
             match *adj {
-                adjustment::AdjustReifyFnPointer=> {
+                adjustment::AdjustReifyFnPointer => {
                     this.emit_enum_variant("AdjustReifyFnPointer", 1, 0, |_| Ok(()))
                 }
 
@@ -620,8 +620,14 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                     })
                 }
 
+                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 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
     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 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
             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 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
                     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::type_of;
 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::tvec;
 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::{self, ObligationCause};
 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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 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 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                         adjustment::AdjustReifyFnPointer
                     }
 
+                    adjustment::AdjustMutToConstPointer => {
+                        adjustment::AdjustMutToConstPointer
+                    }
+
                     adjustment::AdjustUnsafeFnPointer => {
                         adjustment::AdjustUnsafeFnPointer
                     }