@@ -11,7 +11,7 @@ use rustc_hir::def::{CtorKind, Namespace};
1111use rustc_hir:: CoroutineKind ;
1212use rustc_index:: IndexSlice ;
1313use rustc_infer:: infer:: BoundRegionConversionTime ;
14- use rustc_infer:: traits:: { FulfillmentErrorCode , SelectionError , TraitEngine , TraitEngineExt } ;
14+ use rustc_infer:: traits:: { FulfillmentErrorCode , SelectionError } ;
1515use rustc_middle:: mir:: tcx:: PlaceTy ;
1616use rustc_middle:: mir:: {
1717 AggregateKind , CallSource , ConstOperand , FakeReadCause , Local , LocalInfo , LocalKind , Location ,
@@ -25,11 +25,9 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
2525use rustc_span:: def_id:: LocalDefId ;
2626use rustc_span:: { symbol:: sym, Span , Symbol , DUMMY_SP } ;
2727use rustc_target:: abi:: { FieldIdx , VariantIdx } ;
28- use rustc_trait_selection:: solve :: FulfillmentCtxt ;
28+ use rustc_trait_selection:: infer :: InferCtxtExt ;
2929use rustc_trait_selection:: traits:: error_reporting:: suggestions:: TypeErrCtxtExt as _;
30- use rustc_trait_selection:: traits:: {
31- type_known_to_meet_bound_modulo_regions, Obligation , ObligationCause ,
32- } ;
30+ use rustc_trait_selection:: traits:: type_known_to_meet_bound_modulo_regions;
3331
3432use super :: borrow_set:: BorrowData ;
3533use super :: MirBorrowckCtxt ;
@@ -1175,113 +1173,56 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11751173 } else {
11761174 vec ! [ ( move_span. shrink_to_hi( ) , ".clone()" . to_string( ) ) ]
11771175 } ;
1178- self . infcx . probe ( |_snapshot| {
1179- if let ty:: Adt ( def, args) = ty. kind ( )
1180- && !has_sugg
1181- && let Some ( ( def_id, _imp) ) = tcx
1182- . all_impls ( clone_trait)
1183- . filter_map ( |def_id| {
1184- tcx. impl_trait_ref ( def_id) . map ( |r| ( def_id, r) )
1185- } )
1186- . map ( |( def_id, imp) | ( def_id, imp. skip_binder ( ) ) )
1187- . filter ( |( _, imp) | match imp. self_ty ( ) . peel_refs ( ) . kind ( ) {
1188- ty:: Adt ( i_def, _) if i_def. did ( ) == def. did ( ) => true ,
1189- _ => false ,
1190- } )
1191- . next ( )
1192- {
1193- let mut fulfill_cx = FulfillmentCtxt :: new ( self . infcx ) ;
1194- // We get all obligations from the impl to talk about specific
1195- // trait bounds.
1196- let obligations = tcx
1197- . predicates_of ( def_id)
1198- . instantiate ( tcx, args)
1199- . into_iter ( )
1200- . map ( |( clause, span) | {
1201- Obligation :: new (
1202- tcx,
1203- ObligationCause :: misc (
1204- span,
1205- self . body . source . def_id ( ) . expect_local ( ) ,
1206- ) ,
1207- self . param_env ,
1208- clause,
1209- )
1210- } )
1211- . collect :: < Vec < _ > > ( ) ;
1212- fulfill_cx
1213- . register_predicate_obligations ( self . infcx , obligations) ;
1214- // We also register the parent obligation for the type at hand
1215- // implementing `Clone`, to account for bounds that also need
1216- // to be evaluated, like ensuring that `Self: Clone`.
1217- let trait_ref = ty:: TraitRef :: new ( tcx, clone_trait, [ ty] ) ;
1218- let obligation = Obligation :: new (
1219- tcx,
1220- ObligationCause :: dummy ( ) ,
1221- self . param_env ,
1222- trait_ref,
1223- ) ;
1224- fulfill_cx
1225- . register_predicate_obligation ( self . infcx , obligation) ;
1226- let errors = fulfill_cx. select_all_or_error ( self . infcx ) ;
1227- // We remove the last predicate failure, which corresponds to
1228- // the top-level obligation, because most of the type we only
1229- // care about the other ones, *except* when it is the only one.
1230- // This seems to only be relevant for arbitrary self-types.
1231- // Look at `tests/ui/moves/move-fn-self-receiver.rs`.
1232- let errors = match & errors[ ..] {
1233- errors @ [ ] | errors @ [ _] | [ errors @ .., _] => errors,
1234- } ;
1235- let msg = match & errors[ ..] {
1236- [ ] => "you can `clone` the value and consume it, but this \
1237- might not be your desired behavior"
1238- . to_string ( ) ,
1239- [ error] => {
1240- format ! (
1241- "you could `clone` the value and consume it, if \
1242- the `{}` trait bound could be satisfied",
1243- error. obligation. predicate,
1244- )
1245- }
1246- [ errors @ .., last] => {
1247- format ! (
1248- "you could `clone` the value and consume it, if \
1249- the following trait bounds could be satisfied: {} \
1250- and `{}`",
1251- errors
1252- . iter( )
1253- . map( |e| format!(
1254- "`{}`" ,
1255- e. obligation. predicate
1256- ) )
1257- . collect:: <Vec <_>>( )
1258- . join( ", " ) ,
1259- last. obligation. predicate,
1260- )
1261- }
1262- } ;
1263- err. multipart_suggestion_verbose (
1264- msg,
1265- sugg. clone ( ) ,
1266- Applicability :: MaybeIncorrect ,
1267- ) ;
1268- for error in errors {
1269- if let FulfillmentErrorCode :: CodeSelectionError (
1270- SelectionError :: Unimplemented ,
1271- ) = error. code
1272- && let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait (
1273- pred,
1274- ) ) = error. obligation . predicate . kind ( ) . skip_binder ( )
1275- {
1276- self . infcx . err_ctxt ( ) . suggest_derive (
1277- & error. obligation ,
1278- err,
1279- error. obligation . predicate . kind ( ) . rebind ( pred) ,
1280- ) ;
1281- }
1176+ if let Some ( errors) =
1177+ self . infcx . could_impl_trait ( clone_trait, ty, self . param_env )
1178+ && !has_sugg
1179+ {
1180+ let msg = match & errors[ ..] {
1181+ [ ] => "you can `clone` the value and consume it, but this \
1182+ might not be your desired behavior"
1183+ . to_string ( ) ,
1184+ [ error] => {
1185+ format ! (
1186+ "you could `clone` the value and consume it, if \
1187+ the `{}` trait bound could be satisfied",
1188+ error. obligation. predicate,
1189+ )
1190+ }
1191+ [ errors @ .., last] => {
1192+ format ! (
1193+ "you could `clone` the value and consume it, if \
1194+ the following trait bounds could be satisfied: {} \
1195+ and `{}`",
1196+ errors
1197+ . iter( )
1198+ . map( |e| format!( "`{}`" , e. obligation. predicate) )
1199+ . collect:: <Vec <_>>( )
1200+ . join( ", " ) ,
1201+ last. obligation. predicate,
1202+ )
1203+ }
1204+ } ;
1205+ err. multipart_suggestion_verbose (
1206+ msg,
1207+ sugg. clone ( ) ,
1208+ Applicability :: MaybeIncorrect ,
1209+ ) ;
1210+ for error in errors {
1211+ if let FulfillmentErrorCode :: CodeSelectionError (
1212+ SelectionError :: Unimplemented ,
1213+ ) = error. code
1214+ && let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait (
1215+ pred,
1216+ ) ) = error. obligation . predicate . kind ( ) . skip_binder ( )
1217+ {
1218+ self . infcx . err_ctxt ( ) . suggest_derive (
1219+ & error. obligation ,
1220+ err,
1221+ error. obligation . predicate . kind ( ) . rebind ( pred) ,
1222+ ) ;
12821223 }
12831224 }
1284- } ) ;
1225+ }
12851226 }
12861227 }
12871228 }
0 commit comments