diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 048733f837c5..a75f35be1f34 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`") .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`") .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(); } } }