@@ -6,7 +6,7 @@ use rustc_errors::{Applicability, Diagnostic};
6
6
use rustc_hir as hir;
7
7
use rustc_hir:: def:: { CtorKind , Namespace } ;
8
8
use rustc_hir:: GeneratorKind ;
9
- use rustc_infer:: infer:: TyCtxtInferExt ;
9
+ use rustc_infer:: infer:: { LateBoundRegionConversionTime , TyCtxtInferExt } ;
10
10
use rustc_middle:: mir:: tcx:: PlaceTy ;
11
11
use rustc_middle:: mir:: {
12
12
AggregateKind , Constant , FakeReadCause , Field , Local , LocalInfo , LocalKind , Location , Operand ,
@@ -18,7 +18,10 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
18
18
use rustc_span:: def_id:: LocalDefId ;
19
19
use rustc_span:: { symbol:: sym, Span , Symbol , DUMMY_SP } ;
20
20
use rustc_target:: abi:: VariantIdx ;
21
- use rustc_trait_selection:: traits:: type_known_to_meet_bound_modulo_regions;
21
+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
22
+ use rustc_trait_selection:: traits:: {
23
+ type_known_to_meet_bound_modulo_regions, Obligation , ObligationCause ,
24
+ } ;
22
25
23
26
use super :: borrow_set:: BorrowData ;
24
27
use super :: MirBorrowckCtxt ;
@@ -1066,18 +1069,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1066
1069
}
1067
1070
CallKind :: Normal { self_arg, desugaring, method_did } => {
1068
1071
let self_arg = self_arg. unwrap ( ) ;
1072
+ let tcx = self . infcx . tcx ;
1069
1073
if let Some ( ( CallDesugaringKind :: ForLoopIntoIter , _) ) = desugaring {
1070
- let ty = moved_place. ty ( self . body , self . infcx . tcx ) . ty ;
1071
- let suggest = match self . infcx . tcx . get_diagnostic_item ( sym:: IntoIterator ) {
1074
+ let ty = moved_place. ty ( self . body , tcx) . ty ;
1075
+ let suggest = match tcx. get_diagnostic_item ( sym:: IntoIterator ) {
1072
1076
Some ( def_id) => {
1073
1077
let infcx = self . infcx . tcx . infer_ctxt ( ) . build ( ) ;
1074
1078
type_known_to_meet_bound_modulo_regions (
1075
1079
& infcx,
1076
1080
self . param_env ,
1077
- infcx. tcx . mk_imm_ref (
1078
- infcx. tcx . lifetimes . re_erased ,
1079
- infcx. tcx . erase_regions ( ty) ,
1080
- ) ,
1081
+ tcx. mk_imm_ref ( tcx. lifetimes . re_erased , tcx. erase_regions ( ty) ) ,
1081
1082
def_id,
1082
1083
DUMMY_SP ,
1083
1084
)
@@ -1133,8 +1134,44 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1133
1134
place_name, partially_str, loop_message
1134
1135
) ,
1135
1136
) ;
1137
+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
1138
+ let ty = tcx. erase_regions ( moved_place. ty ( self . body , tcx) . ty ) ;
1139
+ if let ty:: Adt ( def, substs) = ty. kind ( )
1140
+ && Some ( def. did ( ) ) == tcx. lang_items ( ) . pin_type ( )
1141
+ && let ty:: Ref ( _, _, hir:: Mutability :: Mut ) = substs. type_at ( 0 ) . kind ( )
1142
+ && let self_ty = infcx. replace_bound_vars_with_fresh_vars (
1143
+ fn_call_span,
1144
+ LateBoundRegionConversionTime :: FnCall ,
1145
+ tcx. fn_sig ( method_did) . input ( 0 ) ,
1146
+ )
1147
+ && infcx. can_eq ( self . param_env , ty, self_ty) . is_ok ( )
1148
+ {
1149
+ err. span_suggestion_verbose (
1150
+ fn_call_span. shrink_to_lo ( ) ,
1151
+ "consider reborrowing the `Pin` instead of moving it" ,
1152
+ "as_mut()." . to_string ( ) ,
1153
+ Applicability :: MaybeIncorrect ,
1154
+ ) ;
1155
+ }
1156
+ if let Some ( clone_trait) = tcx. lang_items ( ) . clone_trait ( )
1157
+ && let trait_ref = tcx. mk_trait_ref ( clone_trait, [ ty] )
1158
+ && let o = Obligation :: new (
1159
+ tcx,
1160
+ ObligationCause :: dummy ( ) ,
1161
+ self . param_env ,
1162
+ ty:: Binder :: dummy ( trait_ref) ,
1163
+ )
1164
+ && infcx. predicate_must_hold_modulo_regions ( & o)
1165
+ {
1166
+ err. span_suggestion_verbose (
1167
+ fn_call_span. shrink_to_lo ( ) ,
1168
+ "you can `clone` the value and consume it, but this might not be \
1169
+ your desired behavior",
1170
+ "clone()." . to_string ( ) ,
1171
+ Applicability :: MaybeIncorrect ,
1172
+ ) ;
1173
+ }
1136
1174
}
1137
- let tcx = self . infcx . tcx ;
1138
1175
// Avoid pointing to the same function in multiple different
1139
1176
// error messages.
1140
1177
if span != DUMMY_SP && self . fn_self_span_reported . insert ( self_arg. span ) {
0 commit comments