@@ -6,7 +6,7 @@ use rustc_errors::{Applicability, Diagnostic};
66use rustc_hir as hir;
77use rustc_hir:: def:: { CtorKind , Namespace } ;
88use rustc_hir:: GeneratorKind ;
9- use rustc_infer:: infer:: TyCtxtInferExt ;
9+ use rustc_infer:: infer:: { LateBoundRegionConversionTime , TyCtxtInferExt } ;
1010use rustc_middle:: mir:: tcx:: PlaceTy ;
1111use rustc_middle:: mir:: {
1212 AggregateKind , Constant , FakeReadCause , Field , Local , LocalInfo , LocalKind , Location , Operand ,
@@ -18,7 +18,10 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
1818use rustc_span:: def_id:: LocalDefId ;
1919use rustc_span:: { symbol:: sym, Span , Symbol , DUMMY_SP } ;
2020use 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+ } ;
2225
2326use super :: borrow_set:: BorrowData ;
2427use super :: MirBorrowckCtxt ;
@@ -1131,13 +1134,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11311134 place_name, partially_str, loop_message
11321135 ) ,
11331136 ) ;
1134- let ty = tcx. erase_regions ( moved_place. ty ( self . body , self . infcx . tcx ) . ty ) ;
1137+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
1138+ let ty = infcx. freshen ( moved_place. ty ( self . body , tcx) . ty ) ;
11351139 if let ty:: Adt ( def, substs) = ty. kind ( )
1136- && Some ( def. did ( ) ) == self . infcx . tcx . lang_items ( ) . pin_type ( )
1140+ && Some ( def. did ( ) ) == tcx. lang_items ( ) . pin_type ( )
11371141 && let ty:: Ref ( _, _, hir:: Mutability :: Mut ) = substs. type_at ( 0 ) . kind ( )
1138- // FIXME: this is a hack because we can't call `can_eq`
1139- && ty. to_string ( ) ==
1140- tcx. fn_sig ( method_did) . input ( 0 ) . skip_binder ( ) . to_string ( )
1142+ && let self_ty = infcx. freshen (
1143+ infcx. replace_bound_vars_with_fresh_vars (
1144+ fn_call_span,
1145+ LateBoundRegionConversionTime :: FnCall ,
1146+ tcx. fn_sig ( method_did) . input ( 0 ) ,
1147+ )
1148+ )
1149+ && infcx. can_eq ( self . param_env , ty, self_ty) . is_ok ( )
11411150 {
11421151 err. span_suggestion_verbose (
11431152 fn_call_span. shrink_to_lo ( ) ,
@@ -1146,28 +1155,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11461155 Applicability :: MaybeIncorrect ,
11471156 ) ;
11481157 }
1149- if let Some ( clone_trait) = tcx. lang_items ( ) . clone_trait ( ) {
1150- // We can't use `predicate_may_hold` or `can_eq` without ICEs in
1151- // borrowck because of the inference context, so we do a poor-man's
1152- // version here.
1153- for impl_def_id in tcx. all_impls ( clone_trait) {
1154- if let Some ( def_id) = impl_def_id. as_local ( )
1155- && let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id)
1156- && let hir:: Node :: Item ( hir:: Item {
1157- kind : hir:: ItemKind :: Impl ( _) ,
1158- ..
1159- } ) = tcx. hir ( ) . get ( hir_id)
1160- && tcx. type_of ( impl_def_id) == ty
1161- {
1162- err. span_suggestion_verbose (
1163- fn_call_span. shrink_to_lo ( ) ,
1164- "you can `clone` the value and consume it, but this might \
1165- not be your desired behavior",
1166- "clone()." . to_string ( ) ,
1167- Applicability :: MaybeIncorrect ,
1168- ) ;
1169- }
1170- }
1158+ if let Some ( clone_trait) = tcx. lang_items ( ) . clone_trait ( )
1159+ && let trait_ref = tcx. mk_trait_ref ( clone_trait, [ ty] )
1160+ && let o = Obligation :: new (
1161+ tcx,
1162+ ObligationCause :: dummy ( ) ,
1163+ self . param_env ,
1164+ ty:: Binder :: dummy ( trait_ref) ,
1165+ )
1166+ && infcx. predicate_must_hold_modulo_regions ( & o)
1167+ {
1168+ err. span_suggestion_verbose (
1169+ fn_call_span. shrink_to_lo ( ) ,
1170+ "you can `clone` the value and consume it, but this might not be \
1171+ your desired behavior",
1172+ "clone()." . to_string ( ) ,
1173+ Applicability :: MaybeIncorrect ,
1174+ ) ;
11711175 }
11721176 }
11731177 // Avoid pointing to the same function in multiple different
0 commit comments