Skip to content

Commit

Permalink
Add VecMap::get_value_matching and assert if > 1 element
Browse files Browse the repository at this point in the history
Otherwise is a bug that we want to uncover.
  • Loading branch information
spastorino committed Jul 23, 2021
1 parent b2b7c85 commit d714107
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
27 changes: 23 additions & 4 deletions compiler/rustc_data_structures/src/vec_map.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::borrow::Borrow;
use std::fmt::Debug;
use std::iter::FromIterator;
use std::slice::Iter;
use std::vec::IntoIter;
Expand All @@ -12,7 +13,8 @@ pub struct VecMap<K, V>(Vec<(K, V)>);

impl<K, V> VecMap<K, V>
where
K: PartialEq,
K: Debug + PartialEq,
V: Debug,
{
pub fn new() -> Self {
VecMap(Default::default())
Expand All @@ -37,14 +39,31 @@ where
self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1)
}

/// Returns the value corresponding to the supplied predicate filter.
/// Returns the any value corresponding to the supplied predicate filter.
///
/// The supplied predicate will be applied to each (key, value) pair and it will return a
/// reference to the values where the predicate returns `true`.
pub fn get_by(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
pub fn any_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
self.0.iter().find(|kv| predicate(kv)).map(|elem| &elem.1)
}

/// Returns the value corresponding to the supplied predicate filter. It crashes if there's
/// more than one matching element.
///
/// The supplied predicate will be applied to each (key, value) pair and it will return a
/// reference to the value where the predicate returns `true`.
pub fn get_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
let mut filter = self.0.iter().filter(|kv| predicate(kv));
let (_, value) = filter.next()?;
// This should return just one element, otherwise it's a bug
assert!(
filter.next().is_none(),
"Collection {:?} should have just one matching element",
self
);
Some(value)
}

/// Returns `true` if the map contains a value for the specified key.
///
/// The key may be any borrowed form of the map's key type,
Expand Down Expand Up @@ -131,7 +150,7 @@ impl<K, V> IntoIterator for VecMap<K, V> {
}
}

impl<K: PartialEq, V> Extend<(K, V)> for VecMap<K, V> {
impl<K: PartialEq + Debug, V: Debug> Extend<(K, V)> for VecMap<K, V> {
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
for (k, v) in iter {
self.insert(k, v);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
let concrete_ty = tcx
.mir_borrowck(owner.expect_local())
.concrete_opaque_types
.get_by(|(key, _)| key.def_id == def_id.to_def_id())
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
.map(|concrete_ty| *concrete_ty)
.unwrap_or_else(|| {
tcx.sess.delay_span_bug(
Expand Down Expand Up @@ -531,7 +531,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
.tcx
.typeck(def_id)
.concrete_opaque_types
.get_by(|(key, _)| key.def_id == self.def_id)
.any_value_matching(|(key, _)| key.def_id == self.def_id)
.is_none()
{
debug!("no constraints in typeck results");
Expand Down

0 comments on commit d714107

Please sign in to comment.