1
+ use std:: fmt:: Write ;
2
+
1
3
use rustc_hir:: def:: DefKind ;
2
- use rustc_hir:: def_id:: CRATE_DEF_ID ;
3
- use rustc_middle:: ty:: TyCtxt ;
4
+ use rustc_hir:: def_id:: { LocalDefId , CRATE_DEF_ID } ;
5
+ use rustc_middle:: ty:: { GenericArgs , TyCtxt } ;
4
6
use rustc_span:: symbol:: sym;
5
7
8
+ fn format_variances ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> String {
9
+ let variances = tcx. variances_of ( def_id) ;
10
+ let generics = GenericArgs :: identity_for_item ( tcx, def_id) ;
11
+ // 7 = 2-letter parameter + ": " + 1-letter variance + ", "
12
+ let mut ret = String :: with_capacity ( 2 + 7 * variances. len ( ) ) ;
13
+ ret. push ( '[' ) ;
14
+ for ( arg, variance) in generics. iter ( ) . zip ( variances. iter ( ) ) {
15
+ write ! ( ret, "{arg}: {variance:?}, " ) . unwrap ( ) ;
16
+ }
17
+ // Remove trailing `, `.
18
+ if !variances. is_empty ( ) {
19
+ ret. pop ( ) ;
20
+ ret. pop ( ) ;
21
+ }
22
+ ret. push ( ']' ) ;
23
+ ret
24
+ }
25
+
6
26
pub ( crate ) fn variances ( tcx : TyCtxt < ' _ > ) {
7
27
if tcx. has_attr ( CRATE_DEF_ID , sym:: rustc_variance_of_opaques) {
8
28
for id in tcx. hir ( ) . items ( ) {
9
29
let DefKind :: OpaqueTy = tcx. def_kind ( id. owner_id ) else { continue } ;
10
30
11
- let variances = tcx. variances_of ( id. owner_id ) ;
12
-
13
31
tcx. dcx ( ) . emit_err ( crate :: errors:: VariancesOf {
14
32
span : tcx. def_span ( id. owner_id ) ,
15
- variances : format ! ( "{variances:?}" ) ,
33
+ variances : format_variances ( tcx , id . owner_id . def_id ) ,
16
34
} ) ;
17
35
}
18
36
}
@@ -22,11 +40,9 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
22
40
continue ;
23
41
}
24
42
25
- let variances = tcx. variances_of ( id. owner_id ) ;
26
-
27
43
tcx. dcx ( ) . emit_err ( crate :: errors:: VariancesOf {
28
44
span : tcx. def_span ( id. owner_id ) ,
29
- variances : format ! ( "{variances:?}" ) ,
45
+ variances : format_variances ( tcx , id . owner_id . def_id ) ,
30
46
} ) ;
31
47
}
32
48
}
0 commit comments