@@ -4,7 +4,7 @@ use rustc::infer::type_variable::TypeVariableOriginKind;
4
4
use rustc:: infer:: InferCtxt ;
5
5
use rustc:: ty;
6
6
use rustc:: ty:: fold:: TypeFolder ;
7
- use rustc:: ty:: { Ty , TyCtxt } ;
7
+ use rustc:: ty:: { Ty , TyCtxt , TyVid } ;
8
8
use rustc_data_structures:: fx:: FxHashMap ;
9
9
use rustc_hir:: HirId ;
10
10
@@ -34,10 +34,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TyVarFinder<'a, 'tcx> {
34
34
}
35
35
}
36
36
37
- fn find_questionable_call (
38
- path : InferredPath < ' tcx > ,
37
+ fn find_questionable_call < ' a , ' tcx > (
38
+ path : & ' a InferredPath < ' tcx > ,
39
39
fcx : & FnCtxt < ' a , ' tcx > ,
40
- ) -> Option < Vec < Ty < ' tcx > > > {
40
+ ) -> Option < & ' a [ Ty < ' tcx > ] > {
41
41
let tcx = fcx. tcx ;
42
42
let ty = fcx. infcx . resolve_vars_if_possible ( & path. ty ) ;
43
43
debug ! ( "post_fallback: Fully resolved ty: {:?}" , ty) ;
@@ -48,7 +48,7 @@ fn find_questionable_call(
48
48
debug ! ( "Got substs: {:?}" , substs) ;
49
49
let mut args_inhabited = true ;
50
50
51
- for arg in & * path. args . unwrap ( ) {
51
+ for arg in & * * path. args . as_ref ( ) . unwrap ( ) {
52
52
let resolved_arg = fcx. infcx . resolve_vars_if_possible ( arg) ;
53
53
54
54
if resolved_arg. conservative_is_privately_uninhabited ( tcx) {
@@ -65,7 +65,7 @@ fn find_questionable_call(
65
65
return None ;
66
66
}
67
67
68
- for ( subst_ty, vars) in substs. types ( ) . zip ( path. unresolved_vars . into_iter ( ) ) {
68
+ for ( subst_ty, vars) in substs. types ( ) . zip ( path. unresolved_vars . iter ( ) ) {
69
69
let resolved_subst = fcx. infcx . resolve_vars_if_possible ( & subst_ty) ;
70
70
if resolved_subst. conservative_is_privately_uninhabited ( tcx) {
71
71
debug ! ( "post_fallback: Subst is uninhabited: {:?}" , resolved_subst) ;
@@ -86,6 +86,11 @@ fn find_questionable_call(
86
86
return None ;
87
87
}
88
88
89
+ struct VarData {
90
+ best_var : TyVid ,
91
+ best_diverging_var : TyVid ,
92
+ }
93
+
89
94
impl < ' tcx > NeverCompatHandler < ' tcx > {
90
95
pub fn pre_fallback ( fcx : & FnCtxt < ' a , ' tcx > ) -> NeverCompatHandler < ' tcx > {
91
96
let unresolved_paths: FxHashMap < HirId , InferredPath < ' tcx > > = fcx
@@ -136,56 +141,50 @@ impl<'tcx> NeverCompatHandler<'tcx> {
136
141
NeverCompatHandler { unresolved_paths, unconstrained_diverging }
137
142
}
138
143
144
+ fn find_best_vars ( & self , fcx : & FnCtxt < ' a , ' tcx > , vars : & [ Ty < ' tcx > ] ) -> VarData {
145
+ for var in vars {
146
+ for diverging_var in & self . unconstrained_diverging {
147
+ match ( & var. kind , & diverging_var. kind ) {
148
+ ( ty:: Infer ( ty:: InferTy :: TyVar ( vid1) ) , ty:: Infer ( ty:: InferTy :: TyVar ( vid2) ) ) => {
149
+ if fcx. infcx . type_variables . borrow_mut ( ) . sub_unified ( * vid1, * vid2) {
150
+ debug ! (
151
+ "Type variable {:?} is equal to diverging var {:?}" ,
152
+ var, diverging_var
153
+ ) ;
154
+
155
+ debug ! (
156
+ "Var origin: {:?}" ,
157
+ fcx. infcx. type_variables. borrow( ) . var_origin( * vid1)
158
+ ) ;
159
+ return VarData { best_var : * vid1, best_diverging_var : * vid2 } ;
160
+ }
161
+ }
162
+ _ => bug ! ( "Unexpected types: var={:?} diverging_var={:?}" , var, diverging_var) ,
163
+ }
164
+ }
165
+ }
166
+ bug ! ( "No vars were equated to divering vars: {:?}" , vars)
167
+ }
168
+
139
169
pub fn post_fallback ( self , fcx : & FnCtxt < ' a , ' tcx > ) {
140
170
let tcx = fcx. tcx ;
141
- for ( call_id, path) in self . unresolved_paths {
171
+ for ( call_id, path) in & self . unresolved_paths {
142
172
debug ! (
143
173
"post_fallback: resolved ty: {:?} at span {:?} : expr={:?} parent={:?} path={:?}" ,
144
174
path. span,
145
175
path. ty,
146
- tcx. hir( ) . get( call_id) ,
147
- tcx. hir( ) . get( tcx. hir( ) . get_parent_node( call_id) ) ,
176
+ tcx. hir( ) . get( * call_id) ,
177
+ tcx. hir( ) . get( tcx. hir( ) . get_parent_node( * call_id) ) ,
148
178
path
149
179
) ;
150
180
151
181
let span = path. span ;
152
182
if let Some ( vars) = find_questionable_call ( path, fcx) {
153
- let mut best_diverging_var = None ;
154
- let mut best_var = None ;
155
-
156
- for var in vars {
157
- for diverging_var in & self . unconstrained_diverging {
158
- match ( & var. kind , & diverging_var. kind ) {
159
- (
160
- ty:: Infer ( ty:: InferTy :: TyVar ( vid1) ) ,
161
- ty:: Infer ( ty:: InferTy :: TyVar ( vid2) ) ,
162
- ) => {
163
- if fcx. infcx . type_variables . borrow_mut ( ) . sub_unified ( * vid1, * vid2) {
164
- debug ! (
165
- "Type variable {:?} is equal to diverging var {:?}" ,
166
- var, diverging_var
167
- ) ;
168
-
169
- debug ! (
170
- "Var origin: {:?}" ,
171
- fcx. infcx. type_variables. borrow( ) . var_origin( * vid1)
172
- ) ;
173
- best_var = Some ( vid1) ;
174
- best_diverging_var = Some ( vid2) ;
175
- }
176
- }
177
- _ => bug ! (
178
- "Unexpected types: var={:?} diverging_var={:?}" ,
179
- var,
180
- diverging_var
181
- ) ,
182
- }
183
- }
184
- }
183
+ let VarData { best_var, best_diverging_var } = self . find_best_vars ( fcx, & vars) ;
185
184
186
- let var_origin = * fcx. infcx . type_variables . borrow ( ) . var_origin ( * best_var. unwrap ( ) ) ;
185
+ let var_origin = * fcx. infcx . type_variables . borrow ( ) . var_origin ( best_var) ;
187
186
let diverging_var_span =
188
- fcx. infcx . type_variables . borrow ( ) . var_origin ( * best_diverging_var. unwrap ( ) ) . span ;
187
+ fcx. infcx . type_variables . borrow ( ) . var_origin ( best_diverging_var) . span ;
189
188
190
189
let mut err = tcx
191
190
. sess
0 commit comments