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) => {
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.
}
}
- 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),
+ }
}
}