1
- use rustc_data_structures:: fx:: FxHashMap ;
1
+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexSet } ;
2
2
use rustc_data_structures:: vec_map:: VecMap ;
3
3
use rustc_hir:: def_id:: LocalDefId ;
4
4
use rustc_hir:: OpaqueTyOrigin ;
@@ -63,17 +63,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
63
63
opaque_ty_decls : VecMap < OpaqueTypeKey < ' tcx > , ( OpaqueHiddenType < ' tcx > , OpaqueTyOrigin ) > ,
64
64
) -> VecMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
65
65
let mut result: VecMap < LocalDefId , OpaqueHiddenType < ' tcx > > = VecMap :: new ( ) ;
66
+
67
+ let member_constraints: FxHashMap < _ , _ > = self
68
+ . member_constraints
69
+ . all_indices ( )
70
+ . map ( |ci| ( self . member_constraints [ ci] . key , ci) )
71
+ . collect ( ) ;
72
+ debug ! ( ?member_constraints) ;
73
+
66
74
for ( opaque_type_key, ( concrete_type, origin) ) in opaque_ty_decls {
67
75
let substs = opaque_type_key. substs ;
68
76
debug ! ( ?concrete_type, ?substs) ;
69
77
70
78
let mut subst_regions = vec ! [ self . universal_regions. fr_static] ;
71
- let universal_substs = infcx. tcx . fold_regions ( substs, |region, _| {
72
- if let ty:: RePlaceholder ( ..) = region. kind ( ) {
73
- // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
74
- return region;
75
- }
76
- let vid = self . to_region_vid ( region) ;
79
+
80
+ let to_universal_region = |vid, subst_regions : & mut Vec < _ > | {
77
81
trace ! ( ?vid) ;
78
82
let scc = self . constraint_sccs . scc ( vid) ;
79
83
trace ! ( ?scc) ;
@@ -94,10 +98,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
94
98
infcx. tcx . lifetimes . re_static
95
99
}
96
100
}
101
+ } ;
102
+
103
+ // Start by inserting universal regions from the member_constraint choice regions.
104
+ // This will ensure they get precedence when folding the regions in the concrete type.
105
+ if let Some ( & ci) = member_constraints. get ( & opaque_type_key) {
106
+ for & vid in self . member_constraints . choice_regions ( ci) {
107
+ to_universal_region ( vid, & mut subst_regions) ;
108
+ }
109
+ }
110
+ debug ! ( ?subst_regions) ;
111
+
112
+ // Next, insert universal regions from substs, so we can translate regions that appear
113
+ // in them but are not subject to member constraints, for instance closure substs.
114
+ let universal_substs = infcx. tcx . fold_regions ( substs, |region, _| {
115
+ if let ty:: RePlaceholder ( ..) = region. kind ( ) {
116
+ // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
117
+ return region;
118
+ }
119
+ let vid = self . to_region_vid ( region) ;
120
+ to_universal_region ( vid, & mut subst_regions)
97
121
} ) ;
122
+ debug ! ( ?universal_substs) ;
123
+ debug ! ( ?subst_regions) ;
98
124
99
- subst_regions. sort ( ) ;
100
- subst_regions. dedup ( ) ;
125
+ // Deduplicate the set of regions while keeping the chosen order.
126
+ let subst_regions = subst_regions. into_iter ( ) . collect :: < FxIndexSet < _ > > ( ) ;
127
+ debug ! ( ?subst_regions) ;
101
128
102
129
let universal_concrete_type =
103
130
infcx. tcx . fold_regions ( concrete_type, |region, _| match * region {
@@ -108,8 +135,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
108
135
. unwrap_or ( infcx. tcx . lifetimes . re_erased ) ,
109
136
_ => region,
110
137
} ) ;
111
-
112
- debug ! ( ?universal_concrete_type, ?universal_substs) ;
138
+ debug ! ( ?universal_concrete_type) ;
113
139
114
140
let opaque_type_key =
115
141
OpaqueTypeKey { def_id : opaque_type_key. def_id , substs : universal_substs } ;
0 commit comments