+
+ let infcx = tcx.infer_ctxt().build();
+ // Erase and shadow everything that could be passed to the new infcx.
+ let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty);
+ let method_substs = tcx.erase_regions(method_substs);
+
+ if let ty::Adt(def, substs) = ty.kind()
+ && Some(def.did()) == tcx.lang_items().pin_type()
+ && let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
+ && let self_ty = infcx.replace_bound_vars_with_fresh_vars(
+ fn_call_span,
+ LateBoundRegionConversionTime::FnCall,
+ tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
+ )
+ && infcx.can_eq(self.param_env, ty, self_ty).is_ok()
+ {
+ err.span_suggestion_verbose(
+ fn_call_span.shrink_to_lo(),
+ "consider reborrowing the `Pin` instead of moving it",
+ "as_mut().".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ if let Some(clone_trait) = tcx.lang_items().clone_trait()
+ && let trait_ref = tcx.mk_trait_ref(clone_trait, [ty])
+ && let o = Obligation::new(
+ tcx,
+ ObligationCause::dummy(),
+ self.param_env,
+ ty::Binder::dummy(trait_ref),
+ )
+ && infcx.predicate_must_hold_modulo_regions(&o)
+ {
+ err.span_suggestion_verbose(
+ fn_call_span.shrink_to_lo(),
+ "you can `clone` the value and consume it, but this might not be \
+ your desired behavior",
+ "clone().".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }