@@ -38,9 +38,9 @@ use rustc_trait_selection::traits::query::method_autoderef::{
38
38
use rustc_trait_selection::traits::query::CanonicalTyGoal;
39
39
use rustc_trait_selection::traits::NormalizeExt;
40
40
use rustc_trait_selection::traits::{self, ObligationCause};
41
+ use std::cell::RefCell;
41
42
use std::cmp::max;
42
43
use std::iter;
43
- use std::mem;
44
44
use std::ops::Deref;
45
45
46
46
use smallvec::{smallvec, SmallVec};
@@ -62,28 +62,29 @@ struct ProbeContext<'a, 'tcx> {
62
62
63
63
/// This is the OriginalQueryValues for the steps queries
64
64
/// that are answered in steps.
65
- orig_steps_var_values: OriginalQueryValues<'tcx>,
65
+ orig_steps_var_values: &'a OriginalQueryValues<'tcx>,
66
66
steps: &'tcx [CandidateStep<'tcx>],
67
67
68
68
inherent_candidates: Vec<Candidate<'tcx>>,
69
69
extension_candidates: Vec<Candidate<'tcx>>,
70
70
impl_dups: FxHashSet<DefId>,
71
71
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
-
76
72
/// When probing for names, include names that are close to the
77
- /// requested name (by Levensthein distance)
73
+ /// requested name (by Levenshtein distance)
78
74
allow_similar_names: bool,
79
75
80
76
/// Some(candidate) if there is a private candidate
81
77
private_candidate: Option<(DefKind, DefId)>,
82
78
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
+
83
83
/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
84
84
/// for error reporting
85
- unsatisfied_predicates:
85
+ unsatisfied_predicates: RefCell<
86
86
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
87
+ >,
87
88
88
89
scope_expr_id: hir::HirId,
89
90
}
@@ -334,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
334
335
op: OP,
335
336
) -> Result<R, MethodError<'tcx>>
336
337
where
337
- OP: FnOnce(ProbeContext<'a , 'tcx>) -> Result<R, MethodError<'tcx>>,
338
+ OP: FnOnce(ProbeContext<'_ , 'tcx>) -> Result<R, MethodError<'tcx>>,
338
339
{
339
340
let mut orig_values = OriginalQueryValues::default();
340
341
let param_env_and_self_ty = self.canonicalize_query(
@@ -445,7 +446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
445
446
mode,
446
447
method_name,
447
448
return_type,
448
- orig_values,
449
+ & orig_values,
449
450
steps.steps,
450
451
scope_expr_id,
451
452
);
@@ -539,7 +540,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
539
540
mode: Mode,
540
541
method_name: Option<Ident>,
541
542
return_type: Option<Ty<'tcx>>,
542
- orig_steps_var_values: OriginalQueryValues<'tcx>,
543
+ orig_steps_var_values: &'a OriginalQueryValues<'tcx>,
543
544
steps: &'tcx [CandidateStep<'tcx>],
544
545
scope_expr_id: hir::HirId,
545
546
) -> ProbeContext<'a, 'tcx> {
@@ -554,10 +555,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
554
555
impl_dups: FxHashSet::default(),
555
556
orig_steps_var_values,
556
557
steps,
557
- static_candidates: Vec::new(),
558
558
allow_similar_names: false,
559
559
private_candidate: None,
560
- unsatisfied_predicates: Vec::new(),
560
+ static_candidates: RefCell::new(Vec::new()),
561
+ unsatisfied_predicates: RefCell::new(Vec::new()),
561
562
scope_expr_id,
562
563
}
563
564
}
@@ -566,8 +567,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
566
567
self.inherent_candidates.clear();
567
568
self.extension_candidates.clear();
568
569
self.impl_dups.clear();
569
- self.static_candidates.clear();
570
570
self.private_candidate = None;
571
+ self.static_candidates.borrow_mut().clear();
572
+ self.unsatisfied_predicates.borrow_mut().clear();
571
573
}
572
574
573
575
///////////////////////////////////////////////////////////////////////////
@@ -1003,9 +1005,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1003
1005
1004
1006
debug!("pick: actual search failed, assemble diagnostics");
1005
1007
1006
- let static_candidates = mem::take(&mut self.static_candidates);
1008
+ let static_candidates = std:: mem::take(self.static_candidates.get_mut() );
1007
1009
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() );
1009
1011
1010
1012
// things failed, so lets look at all traits, for diagnostic purposes now:
1011
1013
self.reset();
@@ -1050,7 +1052,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1050
1052
}))
1051
1053
}
1052
1054
1053
- fn pick_core(&mut self) -> Option<PickResult<'tcx>> {
1055
+ fn pick_core(&self) -> Option<PickResult<'tcx>> {
1054
1056
let pick = self.pick_all_method(Some(&mut vec![]));
1055
1057
1056
1058
// In this case unstable picking is done by `pick_method`.
@@ -1065,11 +1067,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1065
1067
}
1066
1068
1067
1069
fn pick_all_method(
1068
- &mut self,
1070
+ &self,
1069
1071
mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
1070
1072
) -> Option<PickResult<'tcx>> {
1071
- let steps = self.steps.clone();
1072
- steps
1073
+ self.steps
1073
1074
.iter()
1074
1075
.filter(|step| {
1075
1076
debug!("pick_all_method: step={:?}", step);
@@ -1123,7 +1124,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1123
1124
/// to transparently pass `&mut` pointers, in particular, without consuming
1124
1125
/// them for their entire lifetime.
1125
1126
fn pick_by_value_method(
1126
- &mut self,
1127
+ &self,
1127
1128
step: &CandidateStep<'tcx>,
1128
1129
self_ty: Ty<'tcx>,
1129
1130
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
@@ -1151,7 +1152,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1151
1152
}
1152
1153
1153
1154
fn pick_autorefd_method(
1154
- &mut self,
1155
+ &self,
1155
1156
step: &CandidateStep<'tcx>,
1156
1157
self_ty: Ty<'tcx>,
1157
1158
mutbl: hir::Mutability,
@@ -1177,7 +1178,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1177
1178
/// special case for this is because going from `*mut T` to `*const T` with autoderefs and
1178
1179
/// autorefs would require dereferencing the pointer, which is not safe.
1179
1180
fn pick_const_ptr_method(
1180
- &mut self,
1181
+ &self,
1181
1182
step: &CandidateStep<'tcx>,
1182
1183
self_ty: Ty<'tcx>,
1183
1184
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
@@ -1202,7 +1203,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1202
1203
})
1203
1204
}
1204
1205
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>> {
1206
1207
debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty));
1207
1208
1208
1209
let mut possibly_unsatisfied_predicates = Vec::new();
@@ -1213,7 +1214,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1213
1214
debug!("searching {} candidates", kind);
1214
1215
let res = self.consider_candidates(
1215
1216
self_ty,
1216
- candidates.iter() ,
1217
+ candidates,
1217
1218
&mut possibly_unsatisfied_predicates,
1218
1219
Some(&mut vec![]),
1219
1220
);
@@ -1222,21 +1223,27 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1222
1223
}
1223
1224
}
1224
1225
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
+ }
1234
1239
}
1235
- res
1240
+
1241
+ self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates);
1242
+ None
1236
1243
}
1237
1244
1238
1245
fn pick_method(
1239
- &mut self,
1246
+ &self,
1240
1247
self_ty: Ty<'tcx>,
1241
1248
mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
1242
1249
) -> Option<PickResult<'tcx>> {
@@ -1254,7 +1261,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1254
1261
debug!("searching {} candidates", kind);
1255
1262
let res = self.consider_candidates(
1256
1263
self_ty,
1257
- candidates.iter() ,
1264
+ candidates,
1258
1265
&mut possibly_unsatisfied_predicates,
1259
1266
unstable_candidates.as_deref_mut(),
1260
1267
);
@@ -1266,28 +1273,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1266
1273
// `pick_method` may be called twice for the same self_ty if no stable methods
1267
1274
// match. Only extend once.
1268
1275
if unstable_candidates.is_some() {
1269
- self.unsatisfied_predicates.extend(possibly_unsatisfied_predicates);
1276
+ self.unsatisfied_predicates.borrow_mut(). extend(possibly_unsatisfied_predicates);
1270
1277
}
1271
1278
None
1272
1279
}
1273
1280
1274
- fn consider_candidates<'b, ProbesIter> (
1281
+ fn consider_candidates(
1275
1282
&self,
1276
1283
self_ty: Ty<'tcx>,
1277
- probes: ProbesIter ,
1284
+ candidates: &[Candidate<'tcx>] ,
1278
1285
possibly_unsatisfied_predicates: &mut Vec<(
1279
1286
ty::Predicate<'tcx>,
1280
1287
Option<ty::Predicate<'tcx>>,
1281
1288
Option<ObligationCause<'tcx>>,
1282
1289
)>,
1283
1290
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()
1291
1294
.map(|probe| {
1292
1295
(probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates))
1293
1296
})
@@ -1305,19 +1308,19 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1305
1308
}
1306
1309
1307
1310
if let Some(uc) = &mut unstable_candidates {
1308
- applicable_candidates.retain(|&(p , _)| {
1311
+ applicable_candidates.retain(|&(candidate , _)| {
1309
1312
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)
1311
1314
{
1312
- uc.push((p .clone(), feature));
1315
+ uc.push((candidate .clone(), feature));
1313
1316
return false;
1314
1317
}
1315
1318
true
1316
1319
});
1317
1320
}
1318
1321
1319
1322
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();
1321
1324
return Some(Err(MethodError::Ambiguity(sources)));
1322
1325
}
1323
1326
@@ -1701,7 +1704,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1701
1704
self.mode,
1702
1705
self.method_name,
1703
1706
self.return_type,
1704
- self.orig_steps_var_values.clone() ,
1707
+ & self.orig_steps_var_values,
1705
1708
steps,
1706
1709
self.scope_expr_id,
1707
1710
);
@@ -1763,8 +1766,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1763
1766
// -- but this could be overcome.
1764
1767
}
1765
1768
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);
1768
1771
}
1769
1772
1770
1773
#[instrument(level = "debug", skip(self))]
0 commit comments