8
8
use rustc:: hir:: def_id:: DefId ;
9
9
use rustc:: ty;
10
10
use rustc_data_structures:: fx:: FxHashMap ;
11
- use rustc_data_structures:: sync:: Lrc ;
12
11
13
12
use super :: constraints:: * ;
14
13
use super :: terms:: * ;
@@ -23,7 +22,9 @@ struct SolveContext<'a, 'tcx: 'a> {
23
22
solutions : Vec < ty:: Variance > ,
24
23
}
25
24
26
- pub fn solve_constraints ( constraints_cx : ConstraintContext < ' _ , ' _ > ) -> ty:: CrateVariancesMap {
25
+ pub fn solve_constraints < ' tcx > (
26
+ constraints_cx : ConstraintContext < ' _ , ' tcx >
27
+ ) -> ty:: CrateVariancesMap < ' tcx > {
27
28
let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
28
29
29
30
let mut solutions = vec ! [ ty:: Bivariant ; terms_cx. inferred_terms. len( ) ] ;
@@ -41,9 +42,8 @@ pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::Crate
41
42
} ;
42
43
solutions_cx. solve ( ) ;
43
44
let variances = solutions_cx. create_map ( ) ;
44
- let empty_variance = Lrc :: new ( Vec :: new ( ) ) ;
45
45
46
- ty:: CrateVariancesMap { variances, empty_variance }
46
+ ty:: CrateVariancesMap { variances }
47
47
}
48
48
49
49
impl < ' a , ' tcx > SolveContext < ' a , ' tcx > {
@@ -78,7 +78,23 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
78
78
}
79
79
}
80
80
81
- fn create_map ( & self ) -> FxHashMap < DefId , Lrc < Vec < ty:: Variance > > > {
81
+ fn enforce_const_invariance ( & self , generics : & ty:: Generics , variances : & mut [ ty:: Variance ] ) {
82
+ let tcx = self . terms_cx . tcx ;
83
+
84
+ // Make all const parameters invariant.
85
+ for param in generics. params . iter ( ) {
86
+ if let ty:: GenericParamDefKind :: Const = param. kind {
87
+ variances[ param. index as usize ] = ty:: Invariant ;
88
+ }
89
+ }
90
+
91
+ // Make all the const parameters in the parent invariant (recursively).
92
+ if let Some ( def_id) = generics. parent {
93
+ self . enforce_const_invariance ( tcx. generics_of ( def_id) , variances) ;
94
+ }
95
+ }
96
+
97
+ fn create_map ( & self ) -> FxHashMap < DefId , & ' tcx [ ty:: Variance ] > {
82
98
let tcx = self . terms_cx . tcx ;
83
99
84
100
let solutions = & self . solutions ;
@@ -87,26 +103,21 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
87
103
let generics = tcx. generics_of ( def_id) ;
88
104
let count = generics. count ( ) ;
89
105
90
- let mut variances = solutions[ start..( start + count) ] . to_vec ( ) ;
91
- debug ! ( "id={} variances={:?}" , id, variances) ;
106
+ let variances = tcx. arena . alloc_slice ( & solutions[ start..( start + count) ] ) ;
92
107
93
108
// Const parameters are always invariant.
94
- for ( idx, param) in generics. params . iter ( ) . enumerate ( ) {
95
- if let ty:: GenericParamDefKind :: Const = param. kind {
96
- variances[ idx] = ty:: Invariant ;
97
- }
98
- }
109
+ self . enforce_const_invariance ( generics, variances) ;
99
110
100
111
// Functions are permitted to have unused generic parameters: make those invariant.
101
112
if let ty:: FnDef ( ..) = tcx. type_of ( def_id) . sty {
102
- for variance in & mut variances {
113
+ for variance in variances. iter_mut ( ) {
103
114
if * variance == ty:: Bivariant {
104
115
* variance = ty:: Invariant ;
105
116
}
106
117
}
107
118
}
108
119
109
- ( def_id, Lrc :: new ( variances) )
120
+ ( def_id, & * variances)
110
121
} ) . collect ( )
111
122
}
112
123
0 commit comments