about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs35
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs9
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs62
-rw-r--r--compiler/rustc_middle/src/ty/error.rs5
6 files changed, 47 insertions, 92 deletions
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 1c14c1d35f7..e50d249849f 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -179,12 +179,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // Hack: we know that there are traits implementing Fn for &F
             // where F:Fn and so forth. In the particular case of types
-            // like `x: &mut FnMut()`, if there is a call `x()`, we would
-            // normally translate to `FnMut::call_mut(&mut x, ())`, but
-            // that winds up requiring `mut x: &mut FnMut()`. A little
-            // over the top. The simplest fix by far is to just ignore
-            // this case and deref again, so we wind up with
-            // `FnMut::call_mut(&mut *x, ())`.
+            // like `f: &mut FnMut()`, if there is a call `f()`, we would
+            // normally translate to `FnMut::call_mut(&mut f, ())`, but
+            // that winds up potentially requiring the user to mark their
+            // variable as `mut` which feels unnecessary and unexpected.
+            //
+            //     fn foo(f: &mut impl FnMut()) { f() }
+            //            ^ without this hack `f` would have to be declared as mutable
+            //
+            // The simplest fix by far is to just ignore this case and deref again,
+            // so we wind up with `FnMut::call_mut(&mut *f, ())`.
             ty::Ref(..) if autoderef.step_count() == 0 => {
                 return None;
             }
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 1cea8c9dadc..732b4bec58e 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -46,7 +46,6 @@ use rustc_span::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::infer::InferCtxtExt;
-use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
 
 /// Reifies a cast check to be checked once we have full type information for
 /// a function context.
@@ -727,9 +726,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     debug!(" -> CoercionCast");
                     fcx.typeck_results.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) => {
@@ -741,14 +737,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             };
         }
     }
-
-    fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) {
-        let violations = fcx.tcx.object_safety_violations(did);
-        let mut err = report_object_safety_error(fcx.tcx, 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.
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 6b6d54db506..b2d9d70fbd2 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -195,10 +195,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 debug!("coerce: unsize successful");
                 return unsize;
             }
-            Err(TypeError::ObjectUnsafeCoercion(did)) => {
-                debug!("coerce: unsize not object safe");
-                return Err(TypeError::ObjectUnsafeCoercion(did));
-            }
             Err(error) => {
                 debug!(?error, "coerce: unsize failed");
             }
@@ -498,27 +494,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         target = self.shallow_resolve(target);
         debug!(?source, ?target);
 
-        // These 'if' statements require some explanation.
-        // The `CoerceUnsized` trait is special - it is only
-        // possible to write `impl CoerceUnsized<B> for A` where
-        // A and B have 'matching' fields. This rules out the following
-        // two types of blanket impls:
-        //
-        // `impl<T> CoerceUnsized<T> for SomeType`
-        // `impl<T> CoerceUnsized<SomeType> for T`
-        //
-        // Both of these trigger a special `CoerceUnsized`-related error (E0376)
-        //
-        // We can take advantage of this fact to avoid performing unnecessary work.
-        // If either `source` or `target` is a type variable, then any applicable impl
-        // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`)
-        // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for
-        // SomeType`).
-        //
-        // However, these are exactly the kinds of impls which are forbidden by
-        // the compiler! Therefore, we can be sure that coercion will always fail
-        // when either the source or target type is a type variable. This allows us
-        // to skip performing any trait selection, and immediately bail out.
+        // We don't apply any coercions incase either the source or target
+        // aren't sufficiently well known but tend to instead just equate
+        // them both.
         if source.is_ty_var() {
             debug!("coerce_unsized: source is a TyVar, bailing out");
             return Err(TypeError::Mismatch);
@@ -1101,15 +1079,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Special-case that coercion alone cannot handle:
         // Function items or non-capturing closures of differing IDs or InternalSubsts.
         let (a_sig, b_sig) = {
-            #[allow(rustc::usage_of_ty_tykind)]
-            let is_capturing_closure = |ty: &ty::TyKind<'tcx>| {
-                if let &ty::Closure(closure_def_id, _substs) = ty {
+            let is_capturing_closure = |ty: Ty<'tcx>| {
+                if let &ty::Closure(closure_def_id, _substs) = ty.kind() {
                     self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some()
                 } else {
                     false
                 }
             };
-            if is_capturing_closure(prev_ty.kind()) || is_capturing_closure(new_ty.kind()) {
+            if is_capturing_closure(prev_ty) || is_capturing_closure(new_ty) {
                 (None, None)
             } else {
                 match (prev_ty.kind(), new_ty.kind()) {
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 6d858eacb45..4380e66a0d2 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -343,10 +343,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             &mut orig_values,
         );
 
-        let steps = if mode == Mode::MethodCall {
-            self.tcx.method_autoderef_steps(param_env_and_self_ty)
-        } else {
-            self.probe(|_| {
+        let steps = match mode {
+            Mode::MethodCall => self.tcx.method_autoderef_steps(param_env_and_self_ty),
+            Mode::Path => self.probe(|_| {
                 // Mode::Path - the deref steps is "trivial". This turns
                 // our CanonicalQuery into a "trivial" QueryResponse. This
                 // is a bit inefficient, but I don't think that writing
@@ -375,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     opt_bad_ty: None,
                     reached_recursion_limit: false,
                 }
-            })
+            }),
         };
 
         // If our autoderef loop had reached the recursion limit,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 6b6be7359a5..e2be8fb12d0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1672,40 +1672,34 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             }
         };
 
-        match terr {
-            // Ignore msg for object safe coercion
-            // since E0038 message will be printed
-            TypeError::ObjectUnsafeCoercion(_) => {}
-            _ => {
-                let mut label_or_note = |span: Span, msg: &str| {
-                    if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
-                        diag.span_label(span, msg);
-                    } else {
-                        diag.span_note(span, msg);
-                    }
-                };
-                if let Some((sp, msg)) = secondary_span {
-                    if swap_secondary_and_primary {
-                        let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
-                            expected,
-                            ..
-                        })) = values
-                        {
-                            format!("expected this to be `{}`", expected)
-                        } else {
-                            terr.to_string()
-                        };
-                        label_or_note(sp, &terr);
-                        label_or_note(span, &msg);
-                    } else {
-                        label_or_note(span, &terr.to_string());
-                        label_or_note(sp, &msg);
-                    }
-                } else {
-                    label_or_note(span, &terr.to_string());
-                }
+        let mut label_or_note = |span: Span, msg: &str| {
+            if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
+                diag.span_label(span, msg);
+            } else {
+                diag.span_note(span, msg);
             }
         };
+        if let Some((sp, msg)) = secondary_span {
+            if swap_secondary_and_primary {
+                let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
+                    expected,
+                    ..
+                })) = values
+                {
+                    format!("expected this to be `{}`", expected)
+                } else {
+                    terr.to_string()
+                };
+                label_or_note(sp, &terr);
+                label_or_note(span, &msg);
+            } else {
+                label_or_note(span, &terr.to_string());
+                label_or_note(sp, &msg);
+            }
+        } else {
+            label_or_note(span, &terr.to_string());
+        }
+
         if let Some((expected, found)) = expected_found {
             let (expected_label, found_label, exp_found) = match exp_found {
                 Mismatch::Variable(ef) => (
@@ -1875,9 +1869,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         );
                     }
                 }
-                TypeError::ObjectUnsafeCoercion(_) => {
-                    diag.note_unsuccessful_coercion(found, expected);
-                }
                 _ => {
                     debug!(
                         "note_type_err: exp_found={:?}, expected={:?} found={:?}",
@@ -3122,7 +3113,6 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
                 TypeError::IntrinsicCast => {
                     Error0308("cannot coerce intrinsics to function pointers")
                 }
-                TypeError::ObjectUnsafeCoercion(did) => Error0038(did),
                 _ => Error0308("mismatched types"),
             },
         }
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index a61f41b9c58..d83e17574a0 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -70,7 +70,6 @@ pub enum TypeError<'tcx> {
     CyclicConst(ty::Const<'tcx>),
     ProjectionMismatched(ExpectedFound<DefId>),
     ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>),
-    ObjectUnsafeCoercion(DefId),
     ConstMismatch(ExpectedFound<ty::Const<'tcx>>),
 
     IntrinsicCast,
@@ -222,7 +221,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                 f,
                 "cannot coerce functions with `#[target_feature]` to safe function pointers"
             ),
-            ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"),
         }
     }
 }
@@ -249,8 +247,7 @@ impl<'tcx> TypeError<'tcx> {
             | ProjectionMismatched(_)
             | ExistentialMismatch(_)
             | ConstMismatch(_)
-            | IntrinsicCast
-            | ObjectUnsafeCoercion(_) => true,
+            | IntrinsicCast => true,
         }
     }
 }