diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2753bee499b..e76d9b3c942 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -254,10 +254,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } for a in &adj { - if let Adjust::NeverToAny = a.kind { - if a.target.is_ty_var() { - self.diverging_type_vars.borrow_mut().insert(a.target); - debug!("apply_adjustments: adding `{:?}` as diverging type var", a.target); + match a.kind { + Adjust::NeverToAny => { + if a.target.is_ty_var() { + self.diverging_type_vars.borrow_mut().insert(a.target); + debug!("apply_adjustments: adding `{:?}` as diverging type var", a.target); + } + } + Adjust::Deref(Some(overloaded_deref)) => { + self.enforce_context_effects( + expr.span, + overloaded_deref.method_call(self.tcx), + self.tcx.mk_args(&[a.target.into()]), + ); + } + Adjust::Deref(None) => { + // FIXME(effects): We *could* enforce `&T: ~const Deref` here. + } + Adjust::Pointer(_pointer_coercion) => { + // FIXME(effects): We should probably enforce these. + } + Adjust::ReborrowPin(_mutability) => { + // FIXME(effects): We could enforce these; they correspond to + // `&mut T: DerefMut` tho, so it's kinda moot. + } + Adjust::Borrow(_) => { + // No effects to enforce here. } } } diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index ce27e81813c..f8ab555305f 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -1,5 +1,6 @@ use rustc_abi::FieldIdx; use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::Span; @@ -123,19 +124,18 @@ pub struct OverloadedDeref { } impl OverloadedDeref { - /// Get the zst function item type for this method call. - pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> { + /// Get the [`DefId`] of the method call for the given `Deref`/`DerefMut` trait + /// for this overloaded deref's mutability. + pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId { let trait_def_id = match self.mutbl { hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), }; - let method_def_id = tcx - .associated_items(trait_def_id) + tcx.associated_items(trait_def_id) .in_definition_order() .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() - .def_id; - Ty::new_fn_def(tcx, method_def_id, [source]) + .def_id } } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 0481f715019..06d23d9a968 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -136,7 +136,9 @@ impl<'tcx> Cx<'tcx> { Adjust::Deref(Some(deref)) => { // We don't need to do call adjust_span here since // deref coercions always start with a built-in deref. - let call = deref.method_call(self.tcx(), expr.ty); + let call_def_id = deref.method_call(self.tcx()); + let overloaded_callee = + Ty::new_fn_def(self.tcx(), call_def_id, self.tcx().mk_args(&[expr.ty.into()])); expr = Expr { temp_lifetime, @@ -150,7 +152,13 @@ impl<'tcx> Cx<'tcx> { let expr = Box::new([self.thir.exprs.push(expr)]); - self.overloaded_place(hir_expr, adjustment.target, Some(call), expr, deref.span) + self.overloaded_place( + hir_expr, + adjustment.target, + Some(overloaded_callee), + expr, + deref.span, + ) } Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow { borrow_kind: m.to_borrow_kind(),