X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_typeck%2Fcheck%2Fcast.rs;h=ded655c1ae32af5918b47c3367e704280996661b;hb=a12a32ab652d63e342f482566c767042609ab1a6;hp=dfeb5fb958cd8568e8d66d81000016a8e684af47;hpb=d046ffddc4bd50e04ffc3ff9f766e2ac71f74d50;p=rust.git diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index dfeb5fb958c..ded655c1ae3 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -341,10 +341,7 @@ fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) { tstr); 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. @@ -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), + } } }