]> git.lizzy.rs Git - rust.git/commitdiff
Address review commets
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Thu, 14 May 2015 12:04:49 +0000 (15:04 +0300)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Tue, 19 May 2015 14:42:14 +0000 (17:42 +0300)
I think I didn't run tests properly - my second call to
select_all_obligations_or_error has made 3 tests fail. However, this is
just an error message change - integer fallback never worked with casts.

15 files changed:
src/librustc/middle/cast.rs
src/librustc/middle/check_const.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/expr.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/mod.rs
src/test/compile-fail/associated-types-incomplete-object.rs
src/test/compile-fail/cast-rfc0401.rs
src/test/compile-fail/destructure-trait-ref.rs
src/test/compile-fail/issue-17458.rs
src/test/compile-fail/issue-5153.rs
src/test/compile-fail/kindck-impl-type-params.rs
src/test/run-pass-valgrind/cast-enum-with-dtor.rs [new file with mode: 0644]
src/test/run-pass/cast-enum-with-dtor.rs [deleted file]
src/test/run-pass/cast-rfc0401-vtable-kinds.rs

index 4b876cfd80fb6a08298c6a2569a89649daa0cb97..c534a3ca0389fdafa3818743bf49a69805949863 100644 (file)
@@ -15,7 +15,7 @@
 
 use syntax::ast;
 
-
+/// Types that are represented as ints.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum IntTy {
     U(ast::UintTy),
@@ -28,10 +28,16 @@ pub enum IntTy {
 // Valid types for the result of a non-coercion cast
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum CastTy<'tcx> {
+    /// Various types that are represented as ints and handled mostly
+    /// in the same way, merged for easier matching.
     Int(IntTy),
+    /// Floating-Point types
     Float,
-    FPtr,
+    /// Function Pointers
+    FnPtr,
+    /// Raw pointers
     Ptr(&'tcx ty::mt<'tcx>),
+    /// References
     RPtr(&'tcx ty::mt<'tcx>),
 }
 
@@ -47,13 +53,13 @@ pub enum CastKind {
     PrimIntCast,
     U8CharCast,
     ArrayPtrCast,
-    FPtrPtrCast,
-    FPtrAddrCast
+    FnPtrPtrCast,
+    FnPtrAddrCast
 }
 
 impl<'tcx> CastTy<'tcx> {
-    pub fn recognize(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>)
-                     -> Option<CastTy<'tcx>> {
+    pub fn from_ty(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>)
+                   -> Option<CastTy<'tcx>> {
         match t.sty {
             ty::ty_bool => Some(CastTy::Int(IntTy::Bool)),
             ty::ty_char => Some(CastTy::Int(IntTy::Char)),
@@ -64,7 +70,7 @@ pub fn recognize(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>)
                 tcx, t) => Some(CastTy::Int(IntTy::CEnum)),
             ty::ty_ptr(ref mt) => Some(CastTy::Ptr(mt)),
             ty::ty_rptr(_, ref mt) => Some(CastTy::RPtr(mt)),
-            ty::ty_bare_fn(..) => Some(CastTy::FPtr),
+            ty::ty_bare_fn(..) => Some(CastTy::FnPtr),
             _ => None,
         }
     }
index 6d2465a5cb9d2e14bd5346bd91626c19338943f3..794cc4ff38d341c3eb0c5519fbee623fb366a510 100644 (file)
@@ -443,11 +443,11 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             debug!("Checking const cast(id={})", from.id);
             match v.tcx.cast_kinds.borrow().get(&from.id) {
                 None => v.tcx.sess.span_bug(e.span, "no kind for cast"),
-                Some(&CastKind::PtrAddrCast) | Some(&CastKind::FPtrAddrCast) => {
+                Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => {
                     v.add_qualif(ConstQualif::NOT_CONST);
                     if v.mode != Mode::Var {
                         span_err!(v.tcx.sess, e.span, E0018,
-                                  "can not cast a pointer to an integer in {}s", v.msg());
+                                  "can't cast a pointer to an integer in {}s", v.msg());
                     }
                 }
                 _ => {}
index 29430ad10e6403039b7d541ec305da0b2ebef55c..828e4bcc65c4f7965ef3af7f3d239c5fc2722cb1 100644 (file)
@@ -617,41 +617,41 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
               }
           }
           ast::ExprCast(ref base, _) => {
-            let t_1 = ety;
-            let llty = type_of::type_of(cx, t_1);
-            let (v, t_e) = const_expr(cx, &**base, param_substs);
-            debug!("trans_const_cast({} as {})", t_e.repr(cx.tcx()), t_1.repr(cx.tcx()));
-            if expr::cast_is_noop(cx.tcx(), base, t_e, t_1) {
+            let t_cast = ety;
+            let llty = type_of::type_of(cx, t_cast);
+            let (v, t_expr) = const_expr(cx, &**base, param_substs);
+            debug!("trans_const_cast({} as {})", t_expr.repr(cx.tcx()), t_cast.repr(cx.tcx()));
+            if expr::cast_is_noop(cx.tcx(), base, t_expr, t_cast) {
                 return v;
             }
-            if type_is_fat_ptr(cx.tcx(), t_e) {
+            if type_is_fat_ptr(cx.tcx(), t_expr) {
                 // Fat pointer casts.
-                let t_1_inner = ty::deref(t_1, true).expect("cast to non-pointer").ty;
-                let ptr_ty = type_of::in_memory_type_of(cx, t_1_inner).ptr_to();
+                let t_cast_inner = ty::deref(t_cast, true).expect("cast to non-pointer").ty;
+                let ptr_ty = type_of::in_memory_type_of(cx, t_cast_inner).ptr_to();
                 let addr = ptrcast(const_get_elt(cx, v, &[abi::FAT_PTR_ADDR as u32]),
                                    ptr_ty);
-                if type_is_fat_ptr(cx.tcx(), t_1) {
+                if type_is_fat_ptr(cx.tcx(), t_cast) {
                     let info = const_get_elt(cx, v, &[abi::FAT_PTR_EXTRA as u32]);
                     return C_struct(cx, &[addr, info], false)
                 } else {
                     return addr;
                 }
             }
-            match (CastTy::recognize(cx.tcx(), t_e).expect("bad input type for cast"),
-                   CastTy::recognize(cx.tcx(), t_1).expect("bad output type for cast")) {
+            match (CastTy::from_ty(cx.tcx(), t_expr).expect("bad input type for cast"),
+                   CastTy::from_ty(cx.tcx(), t_cast).expect("bad output type for cast")) {
               (CastTy::Int(IntTy::CEnum), CastTy::Int(_)) => {
-                let repr = adt::represent_type(cx, t_e);
+                let repr = adt::represent_type(cx, t_expr);
                 let discr = adt::const_get_discrim(cx, &*repr, v);
                 let iv = C_integral(cx.int_type(), discr, false);
                 let s = adt::is_discr_signed(&*repr) as Bool;
                 llvm::LLVMConstIntCast(iv, llty.to_ref(), s)
               }
               (CastTy::Int(_), CastTy::Int(_)) => {
-                let s = ty::type_is_signed(t_e) as Bool;
+                let s = ty::type_is_signed(t_expr) as Bool;
                 llvm::LLVMConstIntCast(v, llty.to_ref(), s)
               }
               (CastTy::Int(_), CastTy::Float) => {
-                if ty::type_is_signed(t_e) {
+                if ty::type_is_signed(t_expr) {
                     llvm::LLVMConstSIToFP(v, llty.to_ref())
                 } else {
                     llvm::LLVMConstUIToFP(v, llty.to_ref())
@@ -661,18 +661,18 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 llvm::LLVMConstFPCast(v, llty.to_ref())
               }
               (CastTy::Float, CastTy::Int(_)) => {
-                if ty::type_is_signed(t_1) { llvm::LLVMConstFPToSI(v, llty.to_ref()) }
+                if ty::type_is_signed(t_expr) { llvm::LLVMConstFPToSI(v, llty.to_ref()) }
                 else { llvm::LLVMConstFPToUI(v, llty.to_ref()) }
               }
-              (CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FPtr, CastTy::Ptr(_))
+              (CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_))
                     | (CastTy::RPtr(_), CastTy::Ptr(_)) => {
                 ptrcast(v, llty)
               }
-              (CastTy::FPtr, CastTy::FPtr) => ptrcast(v, llty), // isn't this a coercion?
+              (CastTy::FnPtr, CastTy::FnPtr) => ptrcast(v, llty), // isn't this a coercion?
               (CastTy::Int(_), CastTy::Ptr(_)) => {
                 llvm::LLVMConstIntToPtr(v, llty.to_ref())
               }
-              (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FPtr, CastTy::Int(_)) => {
+              (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => {
                 llvm::LLVMConstPtrToInt(v, llty.to_ref())
               }
               _ => {
index e5c9a81818319c19b43701960e2fa616c60c508b..90741d1d58fbc3e32f4e2f0c886368c8b454b089 100644 (file)
@@ -2086,8 +2086,8 @@ fn float_cast(bcx: Block,
         }
     }
 
-    let r_t_in = CastTy::recognize(bcx.tcx(), t_in).expect("bad input type for cast");
-    let r_t_out = CastTy::recognize(bcx.tcx(), t_out).expect("bad output type for cast");
+    let r_t_in = CastTy::from_ty(bcx.tcx(), t_in).expect("bad input type for cast");
+    let r_t_out = CastTy::from_ty(bcx.tcx(), t_out).expect("bad output type for cast");
 
     let (llexpr, signed) = if let Int(CEnum) = r_t_in {
         let repr = adt::represent_type(ccx, t_in);
@@ -2102,8 +2102,10 @@ fn float_cast(bcx: Block,
     };
 
     let newval = match (r_t_in, r_t_out) {
-        (Ptr(_), Ptr(_)) | (FPtr, Ptr(_)) | (RPtr(_), Ptr(_)) => PointerCast(bcx, llexpr, ll_t_out),
-        (Ptr(_), Int(_)) | (FPtr, Int(_)) => PtrToInt(bcx, llexpr, ll_t_out),
+        (Ptr(_), Ptr(_)) | (FnPtr, Ptr(_)) | (RPtr(_), Ptr(_)) => {
+            PointerCast(bcx, llexpr, ll_t_out)
+        }
+        (Ptr(_), Int(_)) | (FnPtr, Int(_)) => PtrToInt(bcx, llexpr, ll_t_out),
         (Int(_), Ptr(_)) => IntToPtr(bcx, llexpr, ll_t_out),
 
         (Int(_), Int(_)) => int_cast(bcx, ll_t_out, ll_t_in, llexpr, signed),
index c3432546b7cf6530ae60d60e2b12d8af5fd87397..5258a77204d60e3f25f949df3ecbced0b7e72ee0 100644 (file)
@@ -56,11 +56,16 @@ pub struct CastCheck<'tcx> {
     span: Span,
 }
 
+/// The kind of the unsize info (length or vtable) - we only allow casts between
+/// fat pointers if their unsize-infos have the same kind.
 #[derive(Copy, Clone, PartialEq, Eq)]
 enum UnsizeKind<'tcx> {
     Vtable,
     Length,
-    OfTy(Ty<'tcx>)
+    /// The unsize info of this projection
+    OfProjection(&'tcx ty::ProjectionTy<'tcx>),
+    /// The unsize info of this parameter
+    OfParam(&'tcx ty::ParamTy)
 }
 
 /// Returns the kind of unsize information of t, or None
@@ -77,8 +82,9 @@ fn unsize_kind<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 Some(f) => unsize_kind(fcx, f.mt.ty)
             }
         }
-        ty::ty_projection(..) | ty::ty_param(..) =>
-            Some(UnsizeKind::OfTy(t)),
+        // We should really try to normalize here.
+        ty::ty_projection(ref pi) => Some(UnsizeKind::OfProjection(pi)),
+        ty::ty_param(ref p) => Some(UnsizeKind::OfParam(p)),
         _ => None
     }
 }
@@ -164,17 +170,17 @@ fn report_cast_error<'a>(&self, fcx: &FnCtxt<'a, 'tcx>,
     }
 
     fn trivial_cast_lint<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
-        let t_1 = self.cast_ty;
-        let t_e = self.expr_ty;
-        if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) {
+        let t_cast = self.cast_ty;
+        let t_expr = self.expr_ty;
+        if ty::type_is_numeric(t_cast) && ty::type_is_numeric(t_expr) {
             fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
                                     self.expr.id,
                                     self.span,
                                     format!("trivial numeric cast: `{}` as `{}`. Cast can be \
                                              replaced by coercion, this might require type \
                                              ascription or a temporary variable",
-                                            fcx.infcx().ty_to_string(t_e),
-                                            fcx.infcx().ty_to_string(t_1)));
+                                            fcx.infcx().ty_to_string(t_expr),
+                                            fcx.infcx().ty_to_string(t_cast)));
         } else {
             fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CASTS,
                                     self.expr.id,
@@ -182,8 +188,8 @@ fn trivial_cast_lint<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
                                     format!("trivial cast: `{}` as `{}`. Cast can be \
                                              replaced by coercion, this might require type \
                                              ascription or a temporary variable",
-                                            fcx.infcx().ty_to_string(t_e),
-                                            fcx.infcx().ty_to_string(t_1)));
+                                            fcx.infcx().ty_to_string(t_expr),
+                                            fcx.infcx().ty_to_string(t_cast)));
         }
 
     }
@@ -211,24 +217,24 @@ pub fn check<'a>(mut self, fcx: &FnCtxt<'a, 'tcx>) {
         };}
     }
 
-    /// Check a cast, and report an error if one exists. In some cases,
-    /// this can return Ok and create type errors rather than returning
+    /// Check a cast, and report an error if one exists. In some cases, this
+    /// can return Ok and create type errors in the fcx rather than returning
     /// directly. coercion-cast is handled in check instead of here.
     fn do_check<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
         use middle::cast::IntTy::*;
         use middle::cast::CastTy::*;
 
-        let (t_e, t_1) = match (CastTy::recognize(fcx.tcx(), self.expr_ty),
-                                CastTy::recognize(fcx.tcx(), self.cast_ty)) {
-            (Some(t_e), Some(t_1)) => (t_e, t_1),
+        let (t_from, t_cast) = match (CastTy::from_ty(fcx.tcx(), self.expr_ty),
+                                      CastTy::from_ty(fcx.tcx(), self.cast_ty)) {
+            (Some(t_from), Some(t_cast)) => (t_from, t_cast),
             _ => {
                 return Err(CastError::NonScalar)
             }
         };
 
-        match (t_e, t_1) {
+        match (t_from, t_cast) {
             // These types have invariants! can't cast into them.
-            (_, RPtr(_)) | (_, Int(CEnum)) | (_, FPtr) => Err(CastError::NonScalar),
+            (_, RPtr(_)) | (_, Int(CEnum)) | (_, FnPtr) => Err(CastError::NonScalar),
 
             // * -> Bool
             (_, Int(Bool)) => Err(CastError::CastToBool),
@@ -244,14 +250,14 @@ fn do_check<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
                 => Err(CastError::NeedViaUsize),
 
             // ptr -> *
-            (Ptr(m1), Ptr(m2)) => self.check_ptr_ptr_cast(fcx, m1, m2), // ptr-ptr-cast
-            (Ptr(m_e), Int(_)) => self.check_ptr_addr_cast(fcx, m_e), // ptr-addr-cast
-            (Ptr(_), Float) | (FPtr, Float) => Err(CastError::NeedViaUsize),
-            (FPtr, Int(_)) => Ok(CastKind::FPtrAddrCast),
+            (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
+            (Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
+            (Ptr(_), Float) | (FnPtr, Float) => Err(CastError::NeedViaUsize),
+            (FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
             (RPtr(_), Int(_)) | (RPtr(_), Float) => Err(CastError::NeedViaPtr),
             // * -> ptr
             (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
-            (FPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
+            (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
             (Float, Ptr(_)) => Err(CastError::NeedViaUsize),
             (RPtr(rmt), Ptr(mt)) => self.check_ref_cast(fcx, rmt, mt), // array-ptr-cast
 
@@ -269,26 +275,26 @@ fn do_check<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
 
     fn check_ptr_ptr_cast<'a>(&self,
                               fcx: &FnCtxt<'a, 'tcx>,
-                              m_e: &'tcx ty::mt<'tcx>,
-                              m_1: &'tcx ty::mt<'tcx>)
+                              m_expr: &'tcx ty::mt<'tcx>,
+                              m_cast: &'tcx ty::mt<'tcx>)
                               -> Result<CastKind, CastError>
     {
-        debug!("check_ptr_ptr_cast m_e={} m_1={}",
-               m_e.repr(fcx.tcx()), m_1.repr(fcx.tcx()));
+        debug!("check_ptr_ptr_cast m_expr={} m_cast={}",
+               m_expr.repr(fcx.tcx()), m_cast.repr(fcx.tcx()));
         // ptr-ptr cast. vtables must match.
 
         // Cast to sized is OK
-        if fcx.type_is_known_to_be_sized(m_1.ty, self.span) {
+        if fcx.type_is_known_to_be_sized(m_cast.ty, self.span) {
             return Ok(CastKind::PtrPtrCast);
         }
 
         // sized -> unsized? report illegal cast (don't complain about vtable kinds)
-        if fcx.type_is_known_to_be_sized(m_e.ty, self.span) {
+        if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
             return Err(CastError::IllegalCast);
         }
 
         // vtable kinds must match
-        match (unsize_kind(fcx, m_1.ty), unsize_kind(fcx, m_e.ty)) {
+        match (unsize_kind(fcx, m_cast.ty), unsize_kind(fcx, m_expr.ty)) {
             (Some(a), Some(b)) if a == b => Ok(CastKind::PtrPtrCast),
             _ => Err(CastError::DifferingKinds)
         }
@@ -296,13 +302,13 @@ fn check_ptr_ptr_cast<'a>(&self,
 
     fn check_fptr_ptr_cast<'a>(&self,
                                fcx: &FnCtxt<'a, 'tcx>,
-                               m_1: &'tcx ty::mt<'tcx>)
+                               m_cast: &'tcx ty::mt<'tcx>)
                                -> Result<CastKind, CastError>
     {
         // fptr-ptr cast. must be to sized ptr
 
-        if fcx.type_is_known_to_be_sized(m_1.ty, self.span) {
-            Ok(CastKind::FPtrPtrCast)
+        if fcx.type_is_known_to_be_sized(m_cast.ty, self.span) {
+            Ok(CastKind::FnPtrPtrCast)
         } else {
             Err(CastError::IllegalCast)
         }
@@ -310,12 +316,12 @@ fn check_fptr_ptr_cast<'a>(&self,
 
     fn check_ptr_addr_cast<'a>(&self,
                                fcx: &FnCtxt<'a, 'tcx>,
-                               m_e: &'tcx ty::mt<'tcx>)
+                               m_expr: &'tcx ty::mt<'tcx>)
                                -> Result<CastKind, CastError>
     {
         // ptr-addr cast. must be from sized ptr
 
-        if fcx.type_is_known_to_be_sized(m_e.ty, self.span) {
+        if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
             Ok(CastKind::PtrAddrCast)
         } else {
             Err(CastError::NeedViaPtr)
@@ -324,14 +330,14 @@ fn check_ptr_addr_cast<'a>(&self,
 
     fn check_ref_cast<'a>(&self,
                           fcx: &FnCtxt<'a, 'tcx>,
-                          m_e: &'tcx ty::mt<'tcx>,
-                          m_1: &'tcx ty::mt<'tcx>)
+                          m_expr: &'tcx ty::mt<'tcx>,
+                          m_cast: &'tcx ty::mt<'tcx>)
                           -> Result<CastKind, CastError>
     {
         // array-ptr-cast.
 
-        if m_e.mutbl == ast::MutImmutable && m_1.mutbl == ast::MutImmutable {
-            if let ty::ty_vec(ety, Some(_)) = m_e.ty.sty {
+        if m_expr.mutbl == ast::MutImmutable && m_cast.mutbl == ast::MutImmutable {
+            if let ty::ty_vec(ety, Some(_)) = m_expr.ty.sty {
                 // Due to the limitations of LLVM global constants,
                 // region pointers end up pointing at copies of
                 // vector elements instead of the original values.
@@ -340,7 +346,7 @@ fn check_ref_cast<'a>(&self,
                 // from a region pointer to a vector.
 
                 // this will report a type mismatch if needed
-                demand::eqtype(fcx, self.span, ety, m_1.ty);
+                demand::eqtype(fcx, self.span, ety, m_cast.ty);
                 return Ok(CastKind::ArrayPtrCast);
             }
         }
@@ -350,11 +356,11 @@ fn check_ref_cast<'a>(&self,
 
     fn check_addr_ptr_cast<'a>(&self,
                                fcx: &FnCtxt<'a, 'tcx>,
-                               m_1: &'tcx ty::mt<'tcx>)
+                               m_cast: &'tcx ty::mt<'tcx>)
                                -> Result<CastKind, CastError>
     {
         // ptr-addr cast. pointer must be thin.
-        if fcx.type_is_known_to_be_sized(m_1.ty, self.span) {
+        if fcx.type_is_known_to_be_sized(m_cast.ty, self.span) {
            Ok(CastKind::AddrPtrCast)
         } else {
            Err(CastError::IllegalCast)
index d5e3139016f211e0ebdc1ba5102f389fdc57f6a3..0e64063d6a402f9981cf9de84f8a5e14b0cd1209 100644 (file)
@@ -1115,20 +1115,20 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                          span: Span,
                                          t_span: Span,
                                          e_span: Span,
-                                         t_1: Ty<'tcx>,
-                                         t_e: Ty<'tcx>,
+                                         t_cast: Ty<'tcx>,
+                                         t_expr: Ty<'tcx>,
                                          id: ast::NodeId) {
-    let tstr = fcx.infcx().ty_to_string(t_1);
+    let tstr = fcx.infcx().ty_to_string(t_cast);
     fcx.type_error_message(span, |actual| {
         format!("cast to unsized type: `{}` as `{}`", actual, tstr)
-    }, t_e, None);
-    match t_e.sty {
+    }, t_expr, None);
+    match t_expr.sty {
         ty::ty_rptr(_, ty::mt { mutbl: mt, .. }) => {
             let mtstr = match mt {
                 ast::MutMutable => "mut ",
                 ast::MutImmutable => ""
             };
-            if ty::type_is_trait(t_1) {
+            if ty::type_is_trait(t_cast) {
                 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
                     Ok(s) => {
                         fcx.tcx().sess.span_suggestion(t_span,
@@ -3404,24 +3404,24 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
 
         // Find the type of `e`. Supply hints based on the type we are casting to,
         // if appropriate.
-        let t_1 = fcx.to_ty(t);
-        let t_1 = structurally_resolved_type(fcx, expr.span, t_1);
-        check_expr_with_expectation(fcx, e, ExpectCastableToType(t_1));
-        let t_e = fcx.expr_ty(e);
+        let t_cast = fcx.to_ty(t);
+        let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
+        check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
+        let t_expr = fcx.expr_ty(e);
 
         // Eagerly check for some obvious errors.
-        if ty::type_is_error(t_e) {
+        if ty::type_is_error(t_expr) {
             fcx.write_error(id);
-        } else if !fcx.type_is_known_to_be_sized(t_1, expr.span) {
-            report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_1, t_e, id);
+        } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
+            report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
         } else {
             // Write a type for the whole expression, assuming everything is going
             // to work out Ok.
-            fcx.write_ty(id, t_1);
+            fcx.write_ty(id, t_cast);
 
             // Defer other checks until we're done type checking.
             let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
-            let cast_check = cast::CastCheck::new((**e).clone(), t_e, t_1, expr.span);
+            let cast_check = cast::CastCheck::new((**e).clone(), t_expr, t_cast, expr.span);
             deferred_cast_checks.push(cast_check);
         }
       }
index 1c708da30a70707194ef6891c708475f1e04f119..c1feb8ac45900a052d0ae393029bd71787c9e5ac 100644 (file)
@@ -28,15 +28,15 @@ fn boo(&self) -> usize {
 }
 
 pub fn main() {
-    let a = &42 as &Foo<A=usize, B=char>;
+    let a = &42isize as &Foo<A=usize, B=char>;
 
-    let b = &42 as &Foo<A=usize>;
+    let b = &42isize as &Foo<A=usize>;
     //~^ ERROR the value of the associated type `B` (from the trait `Foo`) must be specified
 
-    let c = &42 as &Foo<B=char>;
+    let c = &42isize as &Foo<B=char>;
     //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified
 
-    let d = &42 as &Foo;
+    let d = &42isize as &Foo;
     //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified
     //~| ERROR the value of the associated type `B` (from the trait `Foo`) must be specified
 }
index 69ef5421377a321d18278b5d7a8107f96a1adf2b..f3537e54135084fcef980615feae4c084c75a10e 100644 (file)
@@ -65,6 +65,10 @@ fn main()
     let _ = &f as *const f64; //~ ERROR illegal cast
     let _ = fat_v as usize; //~ ERROR through a raw pointer first
 
+    let a : *const str = "hello";
+    let _ = a as *const Foo;
+    //~^ ERROR `core::marker::Sized` is not implemented for the type `str`
+
     // check no error cascade
     let _ = main.f as *const u32; //~ ERROR attempted access of field
 
index 3f455e148a09be30fb0919dfd00f1279f3b0491e..08db643df00e4736003e083e012f3e9898fbb587 100644 (file)
@@ -28,29 +28,29 @@ fn main() {
     // if n > m, it's a type mismatch error.
 
     // n < m
-    let &x = &(&1 as &T);
-    let &x = &&(&1 as &T);
-    let &&x = &&(&1 as &T);
+    let &x = &(&1isize as &T);
+    let &x = &&(&1isize as &T);
+    let &&x = &&(&1isize as &T);
 
     // n == m
-    let &x = &1 as &T;      //~ ERROR type `&T` cannot be dereferenced
-    let &&x = &(&1 as &T);  //~ ERROR type `&T` cannot be dereferenced
-    let box x = box 1 as Box<T>; //~ ERROR the trait `core::marker::Sized` is not implemented
+    let &x = &1isize as &T;      //~ ERROR type `&T` cannot be dereferenced
+    let &&x = &(&1isize as &T);  //~ ERROR type `&T` cannot be dereferenced
+    let box x = box 1isize as Box<T>; //~ ERROR the trait `core::marker::Sized` is not implemented
 
     // n > m
-    let &&x = &1 as &T;
+    let &&x = &1isize as &T;
     //~^ ERROR mismatched types
     //~| expected `T`
     //~| found `&_`
     //~| expected trait T
     //~| found &-ptr
-    let &&&x = &(&1 as &T);
+    let &&&x = &(&1isize as &T);
     //~^ ERROR mismatched types
     //~| expected `T`
     //~| found `&_`
     //~| expected trait T
     //~| found &-ptr
-    let box box x = box 1 as Box<T>;
+    let box box x = box 1isize as Box<T>;
     //~^ ERROR mismatched types
     //~| expected `T`
     //~| found `Box<_>`
index d6f70ae1e57416498d181cd251d4f80fb423e79b..a3a9e17cb3c0676592539fbc1fd525f5f269deb8 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 static X: usize = 0 as *const usize as usize;
-//~^ ERROR: can not cast a pointer to an integer in statics
+//~^ ERROR: can't cast a pointer to an integer in statics
 
 fn main() {
     assert_eq!(X, 0);
index da32408e199249a400013283b282e565a81e563f..b1d96f9b5277885dbb62dea04ef58c23e3b11f34 100644 (file)
@@ -17,6 +17,6 @@ fn foo(self: Box<isize>) { }
 }
 
 fn main() {
-    (&5 as &Foo).foo();
+    (&5isize as &Foo).foo();
     //~^ ERROR: no method named `foo` found for type `&Foo` in the current scope
 }
index d4ee93e9ca5d665df18e742aa256643c3de90c07..988a7837b59bf13d15c3ffe041701eb17db1d12d 100644 (file)
@@ -28,7 +28,6 @@ fn f<T>(val: T) {
     let a = &t as &Gettable<T>;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
-    //~^^^ ERROR the parameter type `T` may not live long enough
 }
 
 fn g<T>(val: T) {
diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
new file mode 100644 (file)
index 0000000..0bc1e33
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(dead_code)]
+
+// check dtor calling order when casting enums.
+
+use std::sync::atomic;
+use std::sync::atomic::Ordering;
+use std::mem;
+
+enum E {
+    A = 0,
+    B = 1,
+    C = 2
+}
+
+static FLAG: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
+
+impl Drop for E {
+    fn drop(&mut self) {
+        // avoid dtor loop
+        unsafe { mem::forget(mem::replace(self, E::B)) };
+
+        FLAG.store(FLAG.load(Ordering::SeqCst)+1, Ordering::SeqCst);
+    }
+}
+
+fn main() {
+    assert_eq!(FLAG.load(Ordering::SeqCst), 0);
+    {
+        let e = E::C;
+        assert_eq!(e as u32, 2);
+        assert_eq!(FLAG.load(Ordering::SeqCst), 0);
+    }
+    assert_eq!(FLAG.load(Ordering::SeqCst), 1);
+}
diff --git a/src/test/run-pass/cast-enum-with-dtor.rs b/src/test/run-pass/cast-enum-with-dtor.rs
deleted file mode 100644 (file)
index 0bc1e33..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(dead_code)]
-
-// check dtor calling order when casting enums.
-
-use std::sync::atomic;
-use std::sync::atomic::Ordering;
-use std::mem;
-
-enum E {
-    A = 0,
-    B = 1,
-    C = 2
-}
-
-static FLAG: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
-
-impl Drop for E {
-    fn drop(&mut self) {
-        // avoid dtor loop
-        unsafe { mem::forget(mem::replace(self, E::B)) };
-
-        FLAG.store(FLAG.load(Ordering::SeqCst)+1, Ordering::SeqCst);
-    }
-}
-
-fn main() {
-    assert_eq!(FLAG.load(Ordering::SeqCst), 0);
-    {
-        let e = E::C;
-        assert_eq!(e as u32, 2);
-        assert_eq!(FLAG.load(Ordering::SeqCst), 0);
-    }
-    assert_eq!(FLAG.load(Ordering::SeqCst), 1);
-}
index 76516a69f7960ea362ceb7a5d0b2b1ba577032ff..e53d4af8e36cbda323ba468a4f565d78f7678117 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Check that you can cast between different pointers to trait objects
+// whose vtable have the same kind (both lengths, or both trait pointers).
+
 trait Foo<T> {
     fn foo(&self, _: T) -> u32 { 42 }
 }