@@ -38,9 +38,9 @@ use rustc_trait_selection::traits::query::method_autoderef::{
3838use rustc_trait_selection:: traits:: query:: CanonicalTyGoal ;
3939use rustc_trait_selection:: traits:: NormalizeExt ;
4040use rustc_trait_selection:: traits:: { self , ObligationCause } ;
41+ use std:: cell:: RefCell ;
4142use std:: cmp:: max;
4243use std:: iter;
43- use std:: mem;
4444use std:: ops:: Deref ;
4545
4646use smallvec:: { smallvec, SmallVec } ;
@@ -62,28 +62,29 @@ struct ProbeContext<'a, 'tcx> {
6262
6363 /// This is the OriginalQueryValues for the steps queries
6464 /// that are answered in steps.
65- orig_steps_var_values : OriginalQueryValues < ' tcx > ,
65+ orig_steps_var_values : & ' a OriginalQueryValues < ' tcx > ,
6666 steps : & ' tcx [ CandidateStep < ' tcx > ] ,
6767
6868 inherent_candidates : Vec < Candidate < ' tcx > > ,
6969 extension_candidates : Vec < Candidate < ' tcx > > ,
7070 impl_dups : FxHashSet < DefId > ,
7171
72- /// Collects near misses when the candidate functions are missing a `self` keyword and is only
73- /// used for error reporting
74- static_candidates : Vec < CandidateSource > ,
75-
7672 /// When probing for names, include names that are close to the
77- /// requested name (by Levensthein distance)
73+ /// requested name (by Levenshtein distance)
7874 allow_similar_names : bool ,
7975
8076 /// Some(candidate) if there is a private candidate
8177 private_candidate : Option < ( DefKind , DefId ) > ,
8278
79+ /// Collects near misses when the candidate functions are missing a `self` keyword and is only
80+ /// used for error reporting
81+ static_candidates : RefCell < Vec < CandidateSource > > ,
82+
8383 /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
8484 /// for error reporting
85- unsatisfied_predicates :
85+ unsatisfied_predicates : RefCell <
8686 Vec < ( ty:: Predicate < ' tcx > , Option < ty:: Predicate < ' tcx > > , Option < ObligationCause < ' tcx > > ) > ,
87+ > ,
8788
8889 scope_expr_id : hir:: HirId ,
8990}
@@ -334,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
334335 op : OP ,
335336 ) -> Result < R , MethodError < ' tcx > >
336337 where
337- OP : FnOnce ( ProbeContext < ' a , ' tcx > ) -> Result < R , MethodError < ' tcx > > ,
338+ OP : FnOnce ( ProbeContext < ' _ , ' tcx > ) -> Result < R , MethodError < ' tcx > > ,
338339 {
339340 let mut orig_values = OriginalQueryValues :: default ( ) ;
340341 let param_env_and_self_ty = self . canonicalize_query (
@@ -445,7 +446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
445446 mode,
446447 method_name,
447448 return_type,
448- orig_values,
449+ & orig_values,
449450 steps. steps ,
450451 scope_expr_id,
451452 ) ;
@@ -539,7 +540,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
539540 mode : Mode ,
540541 method_name : Option < Ident > ,
541542 return_type : Option < Ty < ' tcx > > ,
542- orig_steps_var_values : OriginalQueryValues < ' tcx > ,
543+ orig_steps_var_values : & ' a OriginalQueryValues < ' tcx > ,
543544 steps : & ' tcx [ CandidateStep < ' tcx > ] ,
544545 scope_expr_id : hir:: HirId ,
545546 ) -> ProbeContext < ' a , ' tcx > {
@@ -554,10 +555,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
554555 impl_dups : FxHashSet :: default ( ) ,
555556 orig_steps_var_values,
556557 steps,
557- static_candidates : Vec :: new ( ) ,
558558 allow_similar_names : false ,
559559 private_candidate : None ,
560- unsatisfied_predicates : Vec :: new ( ) ,
560+ static_candidates : RefCell :: new ( Vec :: new ( ) ) ,
561+ unsatisfied_predicates : RefCell :: new ( Vec :: new ( ) ) ,
561562 scope_expr_id,
562563 }
563564 }
@@ -566,8 +567,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
566567 self . inherent_candidates . clear ( ) ;
567568 self . extension_candidates . clear ( ) ;
568569 self . impl_dups . clear ( ) ;
569- self . static_candidates . clear ( ) ;
570570 self . private_candidate = None ;
571+ self . static_candidates . borrow_mut ( ) . clear ( ) ;
572+ self . unsatisfied_predicates . borrow_mut ( ) . clear ( ) ;
571573 }
572574
573575 ///////////////////////////////////////////////////////////////////////////
@@ -1003,9 +1005,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
10031005
10041006 debug ! ( "pick: actual search failed, assemble diagnostics" ) ;
10051007
1006- let static_candidates = mem:: take ( & mut self . static_candidates ) ;
1008+ let static_candidates = std :: mem:: take ( self . static_candidates . get_mut ( ) ) ;
10071009 let private_candidate = self . private_candidate . take ( ) ;
1008- let unsatisfied_predicates = mem:: take ( & mut self . unsatisfied_predicates ) ;
1010+ let unsatisfied_predicates = std :: mem:: take ( self . unsatisfied_predicates . get_mut ( ) ) ;
10091011
10101012 // things failed, so lets look at all traits, for diagnostic purposes now:
10111013 self . reset ( ) ;
@@ -1050,7 +1052,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
10501052 } ) )
10511053 }
10521054
1053- fn pick_core ( & mut self ) -> Option < PickResult < ' tcx > > {
1055+ fn pick_core ( & self ) -> Option < PickResult < ' tcx > > {
10541056 let pick = self . pick_all_method ( Some ( & mut vec ! [ ] ) ) ;
10551057
10561058 // In this case unstable picking is done by `pick_method`.
@@ -1065,11 +1067,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
10651067 }
10661068
10671069 fn pick_all_method (
1068- & mut self ,
1070+ & self ,
10691071 mut unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
10701072 ) -> Option < PickResult < ' tcx > > {
1071- let steps = self . steps . clone ( ) ;
1072- steps
1073+ self . steps
10731074 . iter ( )
10741075 . filter ( |step| {
10751076 debug ! ( "pick_all_method: step={:?}" , step) ;
@@ -1123,7 +1124,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11231124 /// to transparently pass `&mut` pointers, in particular, without consuming
11241125 /// them for their entire lifetime.
11251126 fn pick_by_value_method (
1126- & mut self ,
1127+ & self ,
11271128 step : & CandidateStep < ' tcx > ,
11281129 self_ty : Ty < ' tcx > ,
11291130 unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
@@ -1151,7 +1152,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11511152 }
11521153
11531154 fn pick_autorefd_method (
1154- & mut self ,
1155+ & self ,
11551156 step : & CandidateStep < ' tcx > ,
11561157 self_ty : Ty < ' tcx > ,
11571158 mutbl : hir:: Mutability ,
@@ -1177,7 +1178,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11771178 /// special case for this is because going from `*mut T` to `*const T` with autoderefs and
11781179 /// autorefs would require dereferencing the pointer, which is not safe.
11791180 fn pick_const_ptr_method (
1180- & mut self ,
1181+ & self ,
11811182 step : & CandidateStep < ' tcx > ,
11821183 self_ty : Ty < ' tcx > ,
11831184 unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
@@ -1202,7 +1203,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12021203 } )
12031204 }
12041205
1205- fn pick_method_with_unstable ( & mut self , self_ty : Ty < ' tcx > ) -> Option < PickResult < ' tcx > > {
1206+ fn pick_method_with_unstable ( & self , self_ty : Ty < ' tcx > ) -> Option < PickResult < ' tcx > > {
12061207 debug ! ( "pick_method_with_unstable(self_ty={})" , self . ty_to_string( self_ty) ) ;
12071208
12081209 let mut possibly_unsatisfied_predicates = Vec :: new ( ) ;
@@ -1213,7 +1214,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12131214 debug ! ( "searching {} candidates" , kind) ;
12141215 let res = self . consider_candidates (
12151216 self_ty,
1216- candidates. iter ( ) ,
1217+ candidates,
12171218 & mut possibly_unsatisfied_predicates,
12181219 Some ( & mut vec ! [ ] ) ,
12191220 ) ;
@@ -1222,21 +1223,27 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12221223 }
12231224 }
12241225
1225- debug ! ( "searching unstable candidates" ) ;
1226- let res = self . consider_candidates (
1227- self_ty,
1228- self . inherent_candidates . iter ( ) . chain ( & self . extension_candidates ) ,
1229- & mut possibly_unsatisfied_predicates,
1230- None ,
1231- ) ;
1232- if res. is_none ( ) {
1233- self . unsatisfied_predicates . extend ( possibly_unsatisfied_predicates) ;
1226+ for ( kind, candidates) in
1227+ & [ ( "inherent" , & self . inherent_candidates ) , ( "extension" , & self . extension_candidates ) ]
1228+ {
1229+ debug ! ( "searching unstable {kind} candidates" ) ;
1230+ let res = self . consider_candidates (
1231+ self_ty,
1232+ candidates,
1233+ & mut possibly_unsatisfied_predicates,
1234+ None ,
1235+ ) ;
1236+ if res. is_some ( ) {
1237+ return res;
1238+ }
12341239 }
1235- res
1240+
1241+ self . unsatisfied_predicates . borrow_mut ( ) . extend ( possibly_unsatisfied_predicates) ;
1242+ None
12361243 }
12371244
12381245 fn pick_method (
1239- & mut self ,
1246+ & self ,
12401247 self_ty : Ty < ' tcx > ,
12411248 mut unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
12421249 ) -> Option < PickResult < ' tcx > > {
@@ -1254,7 +1261,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12541261 debug ! ( "searching {} candidates" , kind) ;
12551262 let res = self . consider_candidates (
12561263 self_ty,
1257- candidates. iter ( ) ,
1264+ candidates,
12581265 & mut possibly_unsatisfied_predicates,
12591266 unstable_candidates. as_deref_mut ( ) ,
12601267 ) ;
@@ -1266,28 +1273,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12661273 // `pick_method` may be called twice for the same self_ty if no stable methods
12671274 // match. Only extend once.
12681275 if unstable_candidates. is_some ( ) {
1269- self . unsatisfied_predicates . extend ( possibly_unsatisfied_predicates) ;
1276+ self . unsatisfied_predicates . borrow_mut ( ) . extend ( possibly_unsatisfied_predicates) ;
12701277 }
12711278 None
12721279 }
12731280
1274- fn consider_candidates < ' b , ProbesIter > (
1281+ fn consider_candidates (
12751282 & self ,
12761283 self_ty : Ty < ' tcx > ,
1277- probes : ProbesIter ,
1284+ candidates : & [ Candidate < ' tcx > ] ,
12781285 possibly_unsatisfied_predicates : & mut Vec < (
12791286 ty:: Predicate < ' tcx > ,
12801287 Option < ty:: Predicate < ' tcx > > ,
12811288 Option < ObligationCause < ' tcx > > ,
12821289 ) > ,
12831290 mut unstable_candidates : Option < & mut Vec < ( Candidate < ' tcx > , Symbol ) > > ,
1284- ) -> Option < PickResult < ' tcx > >
1285- where
1286- ProbesIter : Iterator < Item = & ' b Candidate < ' tcx > > + Clone ,
1287- ' tcx : ' b ,
1288- {
1289- let mut applicable_candidates: Vec < _ > = probes
1290- . clone ( )
1291+ ) -> Option < PickResult < ' tcx > > {
1292+ let mut applicable_candidates: Vec < _ > = candidates
1293+ . iter ( )
12911294 . map ( |probe| {
12921295 ( probe, self . consider_probe ( self_ty, probe, possibly_unsatisfied_predicates) )
12931296 } )
@@ -1305,19 +1308,19 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13051308 }
13061309
13071310 if let Some ( uc) = & mut unstable_candidates {
1308- applicable_candidates. retain ( |& ( p , _) | {
1311+ applicable_candidates. retain ( |& ( candidate , _) | {
13091312 if let stability:: EvalResult :: Deny { feature, .. } =
1310- self . tcx . eval_stability ( p . item . def_id , None , self . span , None )
1313+ self . tcx . eval_stability ( candidate . item . def_id , None , self . span , None )
13111314 {
1312- uc. push ( ( p . clone ( ) , feature) ) ;
1315+ uc. push ( ( candidate . clone ( ) , feature) ) ;
13131316 return false ;
13141317 }
13151318 true
13161319 } ) ;
13171320 }
13181321
13191322 if applicable_candidates. len ( ) > 1 {
1320- let sources = probes . map ( |p| self . candidate_source ( p, self_ty) ) . collect ( ) ;
1323+ let sources = candidates . iter ( ) . map ( |p| self . candidate_source ( p, self_ty) ) . collect ( ) ;
13211324 return Some ( Err ( MethodError :: Ambiguity ( sources) ) ) ;
13221325 }
13231326
@@ -1701,7 +1704,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17011704 self . mode ,
17021705 self . method_name ,
17031706 self . return_type ,
1704- self . orig_steps_var_values . clone ( ) ,
1707+ & self . orig_steps_var_values ,
17051708 steps,
17061709 self . scope_expr_id ,
17071710 ) ;
@@ -1763,8 +1766,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17631766 // -- but this could be overcome.
17641767 }
17651768
1766- fn record_static_candidate ( & mut self , source : CandidateSource ) {
1767- self . static_candidates . push ( source) ;
1769+ fn record_static_candidate ( & self , source : CandidateSource ) {
1770+ self . static_candidates . borrow_mut ( ) . push ( source) ;
17681771 }
17691772
17701773 #[ instrument( level = "debug" , skip( self ) ) ]
0 commit comments