X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_typeck%2Fcheck%2Fcast.rs;h=ded655c1ae32af5918b47c3367e704280996661b;hb=a12a32ab652d63e342f482566c767042609ab1a6;hp=c216cc92b1e58867ad0c41913276eb3091975d06;hpb=d2b555eef3a0952a55f787bd69a73a29f3fe04e4;p=rust.git diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index c216cc92b1e..ded655c1ae3 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -93,7 +93,7 @@ fn pointer_kind(&self, t: Ty<'tcx>, span: Span) -> return Ok(Some(PointerKind::Thin)); } - Ok(match t.sty { + Ok(match t.kind { ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Dynamic(ref tty, ..) => Some(PointerKind::Vtable(tty.principal_def_id())), @@ -192,7 +192,7 @@ pub fn new( // For better error messages, check for some obviously unsized // cases now. We do a more thorough check at the end, once // inference is more completely known. - match cast_ty.sty { + match cast_ty.kind { ty::Dynamic(..) | ty::Slice(..) => { check.report_cast_to_unsized_type(fcx); Err(ErrorReported) @@ -339,12 +339,9 @@ fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) { "cast to unsized type: `{}` as `{}`", fcx.resolve_vars_if_possible(&self.expr_ty), tstr); - match self.expr_ty.sty { + match self.expr_ty.kind { ty::Ref(_, _, mt) => { - let mtstr = match mt { - hir::MutMutable => "mut ", - hir::MutImmutable => "", - }; + let mtstr = mt.prefix_str(); if self.cast_ty.is_trait() { match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) { Ok(s) => { @@ -428,21 +425,36 @@ pub fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) { self.report_cast_to_unsized_type(fcx); } else if self.expr_ty.references_error() || self.cast_ty.references_error() { // No sense in giving duplicate error messages - } else if self.try_coercion_cast(fcx) { - self.trivial_cast_lint(fcx); - debug!(" -> CoercionCast"); - fcx.tables.borrow_mut().set_coercion_cast(self.expr.hir_id.local_id); - } else { - match self.do_check(fcx) { - Ok(k) => { - debug!(" -> {:?}", k); + match self.try_coercion_cast(fcx) { + Ok(()) => { + self.trivial_cast_lint(fcx); + debug!(" -> CoercionCast"); + fcx.tables.borrow_mut() + .set_coercion_cast(self.expr.hir_id.local_id); + } + Err(ty::error::TypeError::ObjectUnsafeCoercion(did)) => { + self.report_object_unsafe_cast(&fcx, did); + } + Err(_) => { + match self.do_check(fcx) { + Ok(k) => { + debug!(" -> {:?}", k); + } + Err(e) => self.report_cast_error(fcx, e), + }; } - Err(e) => self.report_cast_error(fcx, e), }; } } + fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) { + let violations = fcx.tcx.object_safety_violations(did); + let mut err = fcx.tcx.report_object_safety_error(self.cast_span, did, violations); + err.note(&format!("required by cast to type '{}'", fcx.ty_to_string(self.cast_ty))); + err.emit(); + } + /// Checks 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. @@ -455,7 +467,7 @@ fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result { (Some(t_from), Some(t_cast)) => (t_from, t_cast), // Function item types may need to be reified before casts. (None, Some(t_cast)) => { - if let ty::FnDef(..) = self.expr_ty.sty { + if let ty::FnDef(..) = self.expr_ty.kind { // Attempt a coercion to a fn pointer type. let f = self.expr_ty.fn_sig(fcx.tcx); let res = fcx.try_coerce(self.expr, @@ -505,7 +517,7 @@ fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result { (FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast), (RPtr(p), Int(_)) | (RPtr(p), Float) => { - match p.ty.sty { + match p.ty.kind { ty::Int(_) | ty::Uint(_) | ty::Float(_) => { @@ -616,7 +628,7 @@ fn check_ref_cast( // array-ptr-cast. if m_expr.mutbl == hir::MutImmutable && m_cast.mutbl == hir::MutImmutable { - if let ty::Array(ety, _) = m_expr.ty.sty { + if let ty::Array(ety, _) = m_expr.ty.kind { // Due to the limitations of LLVM global constants, // region pointers end up pointing at copies of // vector elements instead of the original values. @@ -646,8 +658,14 @@ fn check_addr_ptr_cast( } } - fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> bool { - fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No).is_ok() + fn try_coercion_cast( + &self, + fcx: &FnCtxt<'a, 'tcx>, + ) -> Result<(), ty::error::TypeError<'_>> { + match fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No) { + Ok(_) => Ok(()), + Err(err) => Err(err), + } } }