Skip to content

Commit 8649ead

Browse files
committed
Arbitrary self types v2: search less for shadows.
This commit applies constraints to the searches we perform when searching for potential shadows, in order to make that search quicker.
1 parent 31009a5 commit 8649ead

File tree

1 file changed

+73
-11
lines changed
  • compiler/rustc_hir_typeck/src/method

1 file changed

+73
-11
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,30 @@ impl AutorefOrPtrAdjustment {
158158
}
159159
}
160160

161+
/// Criteria to apply when searching for a given Pick. This is used during
162+
/// the search for potentially shadowed methods to ensure we don't search
163+
/// more candidates than strictly necessary.
164+
#[derive(Debug)]
165+
struct PickConstraintsForShadowed {
166+
autoderefs: usize,
167+
receiver_trait_derefs: usize,
168+
def_id: DefId,
169+
}
170+
171+
impl PickConstraintsForShadowed {
172+
fn may_shadow_based_on_autoderefs(&self, autoderefs: usize) -> bool {
173+
autoderefs == self.autoderefs
174+
}
175+
176+
fn may_shadow_based_on_receiver_trait_derefs(&self, receiver_trait_derefs: usize) -> bool {
177+
receiver_trait_derefs != self.receiver_trait_derefs
178+
}
179+
180+
fn may_shadow_based_on_defid(&self, def_id: DefId) -> bool {
181+
def_id != self.def_id
182+
}
183+
}
184+
161185
#[derive(Debug, Clone)]
162186
pub struct Pick<'tcx> {
163187
pub item: ty::AssocItem,
@@ -180,7 +204,6 @@ pub struct Pick<'tcx> {
180204

181205
/// Number of jumps along the Receiver::target chain we followed
182206
/// to identify this method. Used only for deshadowing errors.
183-
#[allow(dead_code)]
184207
pub receiver_trait_derefs: usize,
185208
}
186209

@@ -1156,6 +1179,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
11561179
self_ty,
11571180
hir::Mutability::Not,
11581181
&mut unstable_candidates,
1182+
None,
11591183
);
11601184
// Check for shadowing of a by-mut-ref method by a by-reference method (see comments on check_for_shadowing)
11611185
if let Some(autoref_pick) = autoref_pick {
@@ -1202,6 +1226,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12021226
self_ty,
12031227
hir::Mutability::Mut,
12041228
&mut unstable_candidates,
1229+
None,
12051230
)
12061231
.or_else(|| self.pick_const_ptr_method(step, self_ty, &mut unstable_candidates))
12071232
})
@@ -1224,19 +1249,32 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12241249
/// Report an error in this case.
12251250
fn check_for_shadowed_autorefd_method(
12261251
&self,
1227-
_possible_shadower: &Pick<'tcx>,
1252+
possible_shadower: &Pick<'tcx>,
12281253
step: &CandidateStep<'tcx>,
12291254
self_ty: Ty<'tcx>,
12301255
mutbl: hir::Mutability,
12311256
tracking_unstable_candidates: bool,
12321257
) -> Result<(), MethodError<'tcx>> {
12331258
let mut unstable_candidates_for_shadow_probe =
12341259
if tracking_unstable_candidates { Some(vec![]) } else { None };
1260+
// Set criteria for how we find methods possibly shadowed by 'possible_shadower'
1261+
let pick_constraints = PickConstraintsForShadowed {
1262+
// It's the same `self` type, other than any autoreffing...
1263+
autoderefs: possible_shadower.autoderefs,
1264+
// ... but the method was found in an impl block determined
1265+
// by searching further along the Receiver chain than the other,
1266+
// showing that it's arbitrary self types causing the problem...
1267+
receiver_trait_derefs: possible_shadower.receiver_trait_derefs,
1268+
// ... and they don't end up pointing to the same item in the
1269+
// first place (could happen with things like blanket impls for T)
1270+
def_id: possible_shadower.item.def_id,
1271+
};
12351272
let _potentially_shadowed_pick = self.pick_autorefd_method(
12361273
step,
12371274
self_ty,
12381275
mutbl,
12391276
&mut unstable_candidates_for_shadow_probe,
1277+
Some(&pick_constraints),
12401278
);
12411279

12421280
// At the moment, this function does no checks. A future
@@ -1260,7 +1298,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12601298
return None;
12611299
}
12621300

1263-
self.pick_method(self_ty, unstable_candidates).map(|r| {
1301+
self.pick_method(self_ty, unstable_candidates, None).map(|r| {
12641302
r.map(|mut pick| {
12651303
pick.autoderefs = step.autoderefs;
12661304

@@ -1284,14 +1322,21 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
12841322
self_ty: Ty<'tcx>,
12851323
mutbl: hir::Mutability,
12861324
unstable_candidates: &mut Option<Vec<(Candidate<'tcx>, Symbol)>>,
1325+
pick_constraints: Option<&PickConstraintsForShadowed>,
12871326
) -> Option<PickResult<'tcx>> {
12881327
let tcx = self.tcx;
12891328

1329+
if let Some(pick_constraints) = pick_constraints {
1330+
if !pick_constraints.may_shadow_based_on_autoderefs(step.autoderefs) {
1331+
return None;
1332+
}
1333+
}
1334+
12901335
// In general, during probing we erase regions.
12911336
let region = tcx.lifetimes.re_erased;
12921337

12931338
let autoref_ty = Ty::new_ref(tcx, region, self_ty, mutbl);
1294-
self.pick_method(autoref_ty, unstable_candidates).map(|r| {
1339+
self.pick_method(autoref_ty, unstable_candidates, pick_constraints).map(|r| {
12951340
r.map(|mut pick| {
12961341
pick.autoderefs = step.autoderefs;
12971342
pick.autoref_or_ptr_adjustment =
@@ -1320,7 +1365,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13201365
};
13211366

13221367
let const_ptr_ty = Ty::new_imm_ptr(self.tcx, ty);
1323-
self.pick_method(const_ptr_ty, unstable_candidates).map(|r| {
1368+
self.pick_method(const_ptr_ty, unstable_candidates, None).map(|r| {
13241369
r.map(|mut pick| {
13251370
pick.autoderefs = step.autoderefs;
13261371
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::ToConstPtr);
@@ -1333,6 +1378,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13331378
&self,
13341379
self_ty: Ty<'tcx>,
13351380
unstable_candidates: &mut Option<Vec<(Candidate<'tcx>, Symbol)>>,
1381+
pick_constraints: Option<&PickConstraintsForShadowed>,
13361382
) -> Option<PickResult<'tcx>> {
13371383
debug!("pick_method(self_ty={})", self.ty_to_string(self_ty));
13381384

@@ -1347,24 +1393,29 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13471393
candidates,
13481394
&mut possibly_unsatisfied_predicates,
13491395
unstable_candidates,
1396+
pick_constraints,
13501397
);
13511398
if let Some(pick) = res {
13521399
return Some(pick);
13531400
}
13541401
}
13551402

13561403
if self.private_candidate.get().is_none() {
1357-
if let Some(Ok(pick)) =
1358-
self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], &mut None)
1359-
{
1404+
if let Some(Ok(pick)) = self.consider_candidates(
1405+
self_ty,
1406+
&self.private_candidates,
1407+
&mut vec![],
1408+
&mut None,
1409+
None,
1410+
) {
13601411
self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id)));
13611412
}
13621413
}
13631414

13641415
// `pick_method` may be called twice for the same self_ty if no stable methods
1365-
// match. Only extend once.
1366-
// FIXME: this shouldn't be done when we're probing just for shadowing possibilities.
1367-
if unstable_candidates.is_some() {
1416+
// match. Only extend once. And don't extend if we're just doing a search for
1417+
// shadowed methods, which will result in a Some pick_constraints.
1418+
if unstable_candidates.is_some() && pick_constraints.is_none() {
13681419
self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates);
13691420
}
13701421
None
@@ -1380,9 +1431,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13801431
Option<ObligationCause<'tcx>>,
13811432
)>,
13821433
unstable_candidates: &mut Option<Vec<(Candidate<'tcx>, Symbol)>>,
1434+
pick_constraints: Option<&PickConstraintsForShadowed>,
13831435
) -> Option<PickResult<'tcx>> {
13841436
let mut applicable_candidates: Vec<_> = candidates
13851437
.iter()
1438+
.filter(|candidate| {
1439+
pick_constraints
1440+
.map(|pick_constraints| {
1441+
pick_constraints.may_shadow_based_on_defid(candidate.item.def_id)
1442+
&& pick_constraints.may_shadow_based_on_receiver_trait_derefs(
1443+
candidate.receiver_trait_derefs,
1444+
)
1445+
})
1446+
.unwrap_or(true)
1447+
})
13861448
.map(|probe| {
13871449
(probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates))
13881450
})

0 commit comments

Comments
 (0)