diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2021-07-24 04:30:56 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-24 04:30:56 +0900 |
| commit | d4532903b05b06e25511ec929823909a157cdf2c (patch) | |
| tree | 51ffec3ff631eb98b4221222ec3e41580fe95ac8 /compiler | |
| parent | 0443424954f32d94f847322e85c77df50d44f80f (diff) | |
| parent | c79df8563b805732d6d04767a7d57384f57fcb0e (diff) | |
| download | rust-d4532903b05b06e25511ec929823909a157cdf2c.tar.gz rust-d4532903b05b06e25511ec929823909a157cdf2c.zip | |
Rollup merge of #86410 - spastorino:get_value_matching, r=oli-obk
VecMap::get_value_matching should return just one element r? `@nikomatsakis` Related to #86465 and #87287
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_data_structures/src/vec_map.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect/type_of.rs | 13 |
2 files changed, 33 insertions, 7 deletions
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index e3fa587985d..cc7ec9432fa 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -1,4 +1,5 @@ use std::borrow::Borrow; +use std::fmt::Debug; use std::iter::FromIterator; use std::slice::Iter; use std::vec::IntoIter; @@ -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()) @@ -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, @@ -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); diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 15469cb0066..50e4ba4fe6c 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -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( @@ -512,8 +512,15 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { struct ConstraintLocator<'tcx> { tcx: TyCtxt<'tcx>, + + /// def_id of the opaque type whose defining uses are being checked def_id: DefId, - // (first found type span, actual type) + + /// as we walk the defining uses, we are checking that all of them + /// define the same hidden type. This variable is set to `Some` + /// with the first type that we find, and then later types are + /// checked against it (we also carry the span of that first + /// type). found: Option<(Span, Ty<'tcx>)>, } @@ -531,7 +538,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"); |
