Skip to content

Commit 711f566

Browse files
Rollup merge of rust-lang#155608 - petrochenkov:optmodcmp, r=jdonszelmann
rustc_middle: Implement the `partial_cmp` operation for `DefId`s And use it in `partial_cmp` implementation for visibilities.
2 parents 742cb81 + 66202c8 commit 711f566

1 file changed

Lines changed: 30 additions & 17 deletions

File tree

  • compiler/rustc_middle/src/ty

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -338,18 +338,39 @@ impl TyCtxt<'_> {
338338
self.parent(id.into().to_def_id()).expect_local()
339339
}
340340

341-
pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
342-
if descendant.krate != ancestor.krate {
343-
return false;
341+
/// Compare def-ids based on their position in def-id tree, ancestor def-ids are considered
342+
/// larger than descendant def-ids, and two different def-ids are considered unordered if
343+
/// neither of them is an ancestor of the other.
344+
fn def_id_partial_cmp(self, lhs: DefId, rhs: DefId) -> Option<Ordering> {
345+
// Def-ids from different crates are always unordered.
346+
if lhs.krate != rhs.krate {
347+
return None;
344348
}
345349

346-
while descendant != ancestor {
347-
match self.opt_parent(descendant) {
348-
Some(parent) => descendant = parent,
349-
None => return false,
350+
// Def-ids of parent nodes are always created before def-ids of child nodes
351+
// and have a smaller index, so we only need to search in one direction,
352+
// either from lhs to rhs, or vice versa.
353+
let search = |mut start: DefId, finish: DefId, ord| {
354+
while start.index != finish.index {
355+
match self.opt_parent(start) {
356+
Some(parent) => start.index = parent.index,
357+
None => return None,
358+
}
350359
}
360+
Some(ord)
361+
};
362+
match lhs.index.cmp(&rhs.index) {
363+
Ordering::Equal => Some(Ordering::Equal),
364+
Ordering::Less => search(rhs, lhs, Ordering::Greater),
365+
Ordering::Greater => search(lhs, rhs, Ordering::Less),
351366
}
352-
true
367+
}
368+
369+
pub fn is_descendant_of(self, descendant: DefId, ancestor: DefId) -> bool {
370+
matches!(
371+
self.def_id_partial_cmp(descendant, ancestor),
372+
Some(Ordering::Less | Ordering::Equal)
373+
)
353374
}
354375
}
355376

@@ -391,15 +412,7 @@ impl<Id: Into<DefId>> Visibility<Id> {
391412
(Visibility::Restricted(_), Visibility::Public) => Some(Ordering::Less),
392413
(Visibility::Restricted(lhs_id), Visibility::Restricted(rhs_id)) => {
393414
let (lhs_id, rhs_id) = (lhs_id.into(), rhs_id.into());
394-
if lhs_id == rhs_id {
395-
Some(Ordering::Equal)
396-
} else if tcx.is_descendant_of(rhs_id, lhs_id) {
397-
Some(Ordering::Greater)
398-
} else if tcx.is_descendant_of(lhs_id, rhs_id) {
399-
Some(Ordering::Less)
400-
} else {
401-
None
402-
}
415+
tcx.def_id_partial_cmp(lhs_id, rhs_id)
403416
}
404417
}
405418
}

0 commit comments

Comments
 (0)