Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion compiler/rustc_index/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ impl<I: Idx, T> IndexVec<I, T> {
pub fn append(&mut self, other: &mut Self) {
self.raw.append(&mut other.raw);
}

#[inline]
pub fn debug_map_view(&self) -> IndexSliceMapView<'_, I, T> {
IndexSliceMapView(self.as_slice())
}
}

/// `IndexVec` is often used as a map, so it provides some map-like APIs.
Expand All @@ -220,11 +225,44 @@ impl<I: Idx, T> IndexVec<I, Option<T>> {
pub fn contains(&self, index: I) -> bool {
self.get(index).and_then(Option::as_ref).is_some()
}

/// This debug view will skip printing `None` entries.
/// This is useful when the slice is actually like a map and `None` means
/// a value is absent under that key.
#[inline]
pub fn debug_map_view_compact(&self) -> IndexSliceMapViewCompact<'_, I, T> {
IndexSliceMapViewCompact(self.as_slice())
}
}

pub struct IndexSliceMapView<'a, I: Idx, T>(&'a IndexSlice<I, T>);
pub struct IndexSliceMapViewCompact<'a, I: Idx, T>(&'a IndexSlice<I, Option<T>>);

impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
fmt::Debug::fmt(self.as_slice(), fmt)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just make this the impl for IndexVec and IndexSlice?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, life happened and it took me a while to come back to this.

Yes, we could potentially. I figured that I frequently need to search the value under one particular index in a slice and it has not been possible.

The printout would be a bit verbose, however. Let's see how the dev ergonomics would be.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, since we do not have min_specialization in this crate yet, I will print the keys even when the index type is u32. The debug print seems to be more readable now and I like how layout printout looks like given that indices are clearly labelled.

@dingxiangfei2009 dingxiangfei2009 Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, probably this is still not a good idea.

It turns out, out of convenience, MIR pretty-print uses debug print of IndexVec and IndexSlice. My smaller local tests did not catch this. With this MIR dump got noisier than I felt comfortable.

I would call this impl switch a deferred upgrade then. We probably would fix the MIR printing in another PR, I can imagine.


impl<'a, I: Idx, T: fmt::Debug> fmt::Debug for IndexSliceMapView<'a, I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut entries = fmt.debug_map();
for (idx, val) in self.0.iter_enumerated() {
entries.entry(&idx, val);
}
entries.finish()
}
}

impl<'a, I: Idx, T: fmt::Debug> fmt::Debug for IndexSliceMapViewCompact<'a, I, T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut entries = fmt.debug_map();
for (idx, val) in self.0.iter_enumerated() {
if let Some(val) = val {
entries.entry(&idx, val);
}
}
entries.finish()
}
}

Expand Down
Loading