+ // used to quickly look up the position of a generic parameter
+ let mut index_map: FxHashMap<ty::ParamTy, usize> = FxHashMap::default();
+ // skip binder is ok, since we only use this to find generic parameters and their
+ // positions.
+ for subst in substs.iter() {
+ if let UnpackedKind::Type(ty) = subst.unpack() {
+ if let ty::Param(p) = ty.sty {
+ let idx = index_map.len();
+ if index_map.insert(p, idx).is_some() {
+ // there was already an entry for `p`, meaning a generic parameter
+ // was used twice
+ self.tcx.sess.span_err(
+ span,
+ &format!("defining existential type use restricts existential \
+ type by using the generic parameter `{}` twice", p.name),
+ );
+ return;
+ }
+ } else {
+ self.tcx.sess.delay_span_bug(
+ span,
+ &format!(
+ "non-defining exist ty use in defining scope: {:?}, {:?}",
+ concrete_type, substs,
+ ),
+ );
+ }
+ }
+ }
+ // compute the index within the existential type for each generic parameter used in
+ // the concrete type
+ let indices = concrete_type
+ .subst(self.tcx, substs)
+ .walk()
+ .filter_map(|t| match &t.sty {
+ ty::Param(p) => Some(*index_map.get(p).unwrap()),
+ _ => None,
+ }).collect();
+ if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
+ let mut ty = concrete_type.walk().fuse();