about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/wfcheck.rs29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 048733f837c..a75f35be1f3 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -491,17 +491,40 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
                 .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
                 .code("E0307".into())
                 .emit();
-                return
+                break
             }
         }
 
-        if let ExplicitSelf::Other = ExplicitSelf::determine(fcx, fcx.param_env, self_ty, self_arg_ty) {
+        let self_kind = ExplicitSelf::determine(fcx, fcx.param_env, self_ty, self_arg_ty);
+
+        if let ExplicitSelf::Other = self_kind {
             if !fcx.tcx.sess.features.borrow().arbitrary_self_types {
                 feature_gate::feature_err(&fcx.tcx.sess.parse_sess, "arbitrary_self_types", span,
                     GateIssue::Language, "arbitrary `self` types are unstable")
                 .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`")
                 .emit();
-                return
+            }
+        } else {
+            let rcvr_ty = match self_kind {
+                ExplicitSelf::ByValue => self_ty,
+                ExplicitSelf::ByReference(region, mutbl) => {
+                    fcx.tcx.mk_ref(region, ty::TypeAndMut {
+                        ty: self_ty,
+                        mutbl,
+                    })
+                }
+                ExplicitSelf::ByBox => fcx.tcx.mk_box(self_ty),
+                ExplicitSelf::Other => unreachable!(),
+            };
+            let rcvr_ty = fcx.normalize_associated_types_in(span, &rcvr_ty);
+            let rcvr_ty = fcx.liberate_late_bound_regions(method.def_id,
+                                                        &ty::Binder(rcvr_ty));
+
+            debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
+
+            let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
+            if let Some(mut err) = fcx.demand_eqtype_with_origin(&cause, rcvr_ty, self_arg_ty) {
+                err.emit();
             }
         }
     }