@@ -4,7 +4,7 @@ use rustc::infer::type_variable::TypeVariableOriginKind;
44use rustc:: infer:: InferCtxt ;
55use rustc:: ty;
66use rustc:: ty:: fold:: TypeFolder ;
7- use rustc:: ty:: { Ty , TyCtxt } ;
7+ use rustc:: ty:: { Ty , TyCtxt , TyVid } ;
88use rustc_data_structures:: fx:: FxHashMap ;
99use rustc_hir:: HirId ;
1010
@@ -34,10 +34,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TyVarFinder<'a, 'tcx> {
3434 }
3535}
3636
37- fn find_questionable_call (
38- path : InferredPath < ' tcx > ,
37+ fn find_questionable_call < ' a , ' tcx > (
38+ path : & ' a InferredPath < ' tcx > ,
3939 fcx : & FnCtxt < ' a , ' tcx > ,
40- ) -> Option < Vec < Ty < ' tcx > > > {
40+ ) -> Option < & ' a [ Ty < ' tcx > ] > {
4141 let tcx = fcx. tcx ;
4242 let ty = fcx. infcx . resolve_vars_if_possible ( & path. ty ) ;
4343 debug ! ( "post_fallback: Fully resolved ty: {:?}" , ty) ;
@@ -48,7 +48,7 @@ fn find_questionable_call(
4848 debug ! ( "Got substs: {:?}" , substs) ;
4949 let mut args_inhabited = true ;
5050
51- for arg in & * path. args . unwrap ( ) {
51+ for arg in & * * path. args . as_ref ( ) . unwrap ( ) {
5252 let resolved_arg = fcx. infcx . resolve_vars_if_possible ( arg) ;
5353
5454 if resolved_arg. conservative_is_privately_uninhabited ( tcx) {
@@ -65,7 +65,7 @@ fn find_questionable_call(
6565 return None ;
6666 }
6767
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 ( ) ) {
6969 let resolved_subst = fcx. infcx . resolve_vars_if_possible ( & subst_ty) ;
7070 if resolved_subst. conservative_is_privately_uninhabited ( tcx) {
7171 debug ! ( "post_fallback: Subst is uninhabited: {:?}" , resolved_subst) ;
@@ -86,6 +86,11 @@ fn find_questionable_call(
8686 return None ;
8787}
8888
89+ struct VarData {
90+ best_var : TyVid ,
91+ best_diverging_var : TyVid ,
92+ }
93+
8994impl < ' tcx > NeverCompatHandler < ' tcx > {
9095 pub fn pre_fallback ( fcx : & FnCtxt < ' a , ' tcx > ) -> NeverCompatHandler < ' tcx > {
9196 let unresolved_paths: FxHashMap < HirId , InferredPath < ' tcx > > = fcx
@@ -136,56 +141,50 @@ impl<'tcx> NeverCompatHandler<'tcx> {
136141 NeverCompatHandler { unresolved_paths, unconstrained_diverging }
137142 }
138143
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+
139169 pub fn post_fallback ( self , fcx : & FnCtxt < ' a , ' tcx > ) {
140170 let tcx = fcx. tcx ;
141- for ( call_id, path) in self . unresolved_paths {
171+ for ( call_id, path) in & self . unresolved_paths {
142172 debug ! (
143173 "post_fallback: resolved ty: {:?} at span {:?} : expr={:?} parent={:?} path={:?}" ,
144174 path. span,
145175 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) ) ,
148178 path
149179 ) ;
150180
151181 let span = path. span ;
152182 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) ;
185184
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) ;
187186 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 ;
189188
190189 let mut err = tcx
191190 . sess
0 commit comments