@@ -1355,10 +1355,9 @@ fn find_existential_constraints<'a, 'tcx>(
13551355 let mut index_map: FxHashMap < ty:: ParamTy , usize > = FxHashMap :: default ( ) ;
13561356 // skip binder is ok, since we only use this to find generic parameters and their
13571357 // positions.
1358- for subst in substs. iter ( ) {
1358+ for ( idx , subst) in substs. iter ( ) . enumerate ( ) {
13591359 if let UnpackedKind :: Type ( ty) = subst. unpack ( ) {
13601360 if let ty:: Param ( p) = ty. sty {
1361- let idx = index_map. len ( ) ;
13621361 if index_map. insert ( p, idx) . is_some ( ) {
13631362 // there was already an entry for `p`, meaning a generic parameter
13641363 // was used twice
@@ -1391,20 +1390,24 @@ fn find_existential_constraints<'a, 'tcx>(
13911390 } ) . collect ( ) ;
13921391 if let Some ( ( prev_span, prev_ty, ref prev_indices) ) = self . found {
13931392 let mut ty = concrete_type. walk ( ) . fuse ( ) ;
1394- let mut prev_ty = prev_ty. walk ( ) . fuse ( ) ;
1395- let iter_eq = ( & mut ty) . zip ( & mut prev_ty ) . all ( |( t, p) | match ( & t. sty , & p. sty ) {
1393+ let mut p_ty = prev_ty. walk ( ) . fuse ( ) ;
1394+ let iter_eq = ( & mut ty) . zip ( & mut p_ty ) . all ( |( t, p) | match ( & t. sty , & p. sty ) {
13961395 // type parameters are equal to any other type parameter for the purpose of
13971396 // concrete type equality, as it is possible to obtain the same type just
13981397 // by passing matching parameters to a function.
13991398 ( ty:: Param ( _) , ty:: Param ( _) ) => true ,
14001399 _ => t == p,
14011400 } ) ;
1402- if !iter_eq || ty. next ( ) . is_some ( ) || prev_ty . next ( ) . is_some ( ) {
1401+ if !iter_eq || ty. next ( ) . is_some ( ) || p_ty . next ( ) . is_some ( ) {
14031402 // found different concrete types for the existential type
14041403 let mut err = self . tcx . sess . struct_span_err (
14051404 span,
14061405 "concrete type differs from previous defining existential type use" ,
14071406 ) ;
1407+ err. span_label (
1408+ span,
1409+ format ! ( "expected `{}`, got `{}`" , prev_ty, concrete_type) ,
1410+ ) ;
14081411 err. span_note ( prev_span, "previous use here" ) ;
14091412 err. emit ( ) ;
14101413 } else if indices != * prev_indices {
@@ -1413,6 +1416,23 @@ fn find_existential_constraints<'a, 'tcx>(
14131416 span,
14141417 "concrete type's generic parameters differ from previous defining use" ,
14151418 ) ;
1419+ use std:: fmt:: Write ;
1420+ let mut s = String :: new ( ) ;
1421+ write ! ( s, "expected [" ) . unwrap ( ) ;
1422+ let list = |s : & mut String , indices : & Vec < usize > | {
1423+ let mut indices = indices. iter ( ) . cloned ( ) ;
1424+ if let Some ( first) = indices. next ( ) {
1425+ write ! ( s, "`{}`" , substs[ first] ) . unwrap ( ) ;
1426+ for i in indices {
1427+ write ! ( s, ", `{}`" , substs[ i] ) . unwrap ( ) ;
1428+ }
1429+ }
1430+ } ;
1431+ list ( & mut s, prev_indices) ;
1432+ write ! ( s, "], got [" ) . unwrap ( ) ;
1433+ list ( & mut s, & indices) ;
1434+ write ! ( s, "]" ) . unwrap ( ) ;
1435+ err. span_label ( span, s) ;
14161436 err. span_note ( prev_span, "previous use here" ) ;
14171437 err. emit ( ) ;
14181438 }
0 commit comments