@@ -871,10 +871,21 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
871871 fcx
872872 } ;
873873
874- fcx. select_all_obligations_and_apply_defaults ( ) ;
875- fcx. closure_analyze ( body) ;
874+ // All type checking constraints were added, try to fallback unsolved variables.
875+ fcx. select_obligations_where_possible ( ) ;
876+ for ty in & fcx. unsolved_variables ( ) {
877+ fcx. fallback_if_possible ( ty) ;
878+ }
876879 fcx. select_obligations_where_possible ( ) ;
880+
881+ // Even though coercion casts provide type hints, we check casts after fallback for
882+ // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
877883 fcx. check_casts ( ) ;
884+
885+ // Closure and generater analysis may run after fallback
886+ // because they don't constrain other type variables.
887+ fcx. closure_analyze ( body) ;
888+ assert ! ( fcx. deferred_call_resolutions. borrow( ) . is_empty( ) ) ;
878889 fcx. resolve_generator_interiors ( def_id) ;
879890 fcx. select_all_obligations_or_error ( ) ;
880891
@@ -2143,74 +2154,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21432154 }
21442155 }
21452156
2146- /// Apply "fallbacks" to some types
2147- /// unconstrained types get replaced with ! or () (depending on whether
2148- /// feature(never_type) is enabled), unconstrained ints with i32, and
2149- /// unconstrained floats with f64.
2150- fn default_type_parameters ( & self ) {
2157+ // Tries to apply a fallback to `ty` if it is an unsolved variable.
2158+ // Non-numerics get replaced with ! or () (depending on whether
2159+ // feature(never_type) is enabled), unconstrained ints with i32,
2160+ // unconstrained floats with f64.
2161+ // Fallback becomes very dubious if we have encountered type-checking errors.
2162+ // In that case, fallback to TyError.
2163+ fn fallback_if_possible ( & self , ty : Ty < ' tcx > ) {
21512164 use rustc:: ty:: error:: UnconstrainedNumeric :: Neither ;
21522165 use rustc:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedInt , UnconstrainedFloat } ;
21532166
2154- // Defaulting inference variables becomes very dubious if we have
2155- // encountered type-checking errors. Therefore, if we think we saw
2156- // some errors in this function, just resolve all uninstanted type
2157- // varibles to TyError.
2158- if self . is_tainted_by_errors ( ) {
2159- for ty in & self . unsolved_variables ( ) {
2160- if let ty:: TyInfer ( _) = self . shallow_resolve ( ty) . sty {
2161- debug ! ( "default_type_parameters: defaulting `{:?}` to error" , ty) ;
2162- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx ( ) . types . err ) ;
2163- }
2164- }
2165- return ;
2166- }
2167-
2168- for ty in & self . unsolved_variables ( ) {
2169- let resolved = self . resolve_type_vars_if_possible ( ty) ;
2170- if self . type_var_diverges ( resolved) {
2171- debug ! ( "default_type_parameters: defaulting `{:?}` to `!` because it diverges" ,
2172- resolved) ;
2173- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty,
2174- self . tcx . mk_diverging_default ( ) ) ;
2175- } else {
2176- match self . type_is_unconstrained_numeric ( resolved) {
2177- UnconstrainedInt => {
2178- debug ! ( "default_type_parameters: defaulting `{:?}` to `i32`" ,
2179- resolved) ;
2180- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx . types . i32 )
2181- } ,
2182- UnconstrainedFloat => {
2183- debug ! ( "default_type_parameters: defaulting `{:?}` to `f32`" ,
2184- resolved) ;
2185- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx . types . f64 )
2186- }
2187- Neither => { }
2188- }
2189- }
2190- }
2191- }
2192-
2193- // Implements type inference fallback algorithm
2194- fn select_all_obligations_and_apply_defaults ( & self ) {
2195- self . select_obligations_where_possible ( ) ;
2196- self . default_type_parameters ( ) ;
2197- self . select_obligations_where_possible ( ) ;
2167+ assert ! ( ty. is_ty_infer( ) ) ;
2168+ let fallback = match self . type_is_unconstrained_numeric ( ty) {
2169+ _ if self . is_tainted_by_errors ( ) => self . tcx ( ) . types . err ,
2170+ UnconstrainedInt => self . tcx . types . i32 ,
2171+ UnconstrainedFloat => self . tcx . types . f64 ,
2172+ Neither if self . type_var_diverges ( ty) => self . tcx . mk_diverging_default ( ) ,
2173+ Neither => return
2174+ } ;
2175+ debug ! ( "default_type_parameters: defaulting `{:?}` to `{:?}`" , ty, fallback) ;
2176+ self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty, fallback) ;
21982177 }
21992178
22002179 fn select_all_obligations_or_error ( & self ) {
22012180 debug ! ( "select_all_obligations_or_error" ) ;
2202-
2203- // upvar inference should have ensured that all deferred call
2204- // resolutions are handled by now.
2205- assert ! ( self . deferred_call_resolutions. borrow( ) . is_empty( ) ) ;
2206-
2207- self . select_all_obligations_and_apply_defaults ( ) ;
2208-
2209- let mut fulfillment_cx = self . fulfillment_cx . borrow_mut ( ) ;
2210-
2211- match fulfillment_cx. select_all_or_error ( self ) {
2212- Ok ( ( ) ) => { }
2213- Err ( errors) => { self . report_fulfillment_errors ( & errors, self . inh . body_id ) ; }
2181+ if let Err ( errors) = self . fulfillment_cx . borrow_mut ( ) . select_all_or_error ( & self ) {
2182+ self . report_fulfillment_errors ( & errors, self . inh . body_id ) ;
22142183 }
22152184 }
22162185
@@ -5074,39 +5043,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50745043 } ) ;
50755044 }
50765045
5077- fn structurally_resolve_type_or_else < F > ( & self , sp : Span , ty : Ty < ' tcx > , f : F )
5078- -> Ty < ' tcx >
5079- where F : Fn ( ) -> Ty < ' tcx >
5080- {
5081- let mut ty = self . resolve_type_vars_with_obligations ( ty) ;
5082-
5083- if ty. is_ty_var ( ) {
5084- let alternative = f ( ) ;
5085-
5086- // If not, error.
5087- if alternative. is_ty_var ( ) || alternative. references_error ( ) {
5088- if !self . is_tainted_by_errors ( ) {
5089- type_error_struct ! ( self . tcx. sess, sp, ty, E0619 ,
5090- "the type of this value must be known in this context" )
5091- . emit ( ) ;
5092- }
5093- self . demand_suptype ( sp, self . tcx . types . err , ty) ;
5094- ty = self . tcx . types . err ;
5095- } else {
5096- self . demand_suptype ( sp, alternative, ty) ;
5097- ty = alternative;
5098- }
5099- }
5100-
5101- ty
5102- }
5103-
5104- // Resolves `typ` by a single level if `typ` is a type variable. If no
5105- // resolution is possible, then an error is reported.
5046+ // Resolves `typ` by a single level if `typ` is a type variable.
5047+ // If no resolution is possible, then an error is reported.
5048+ // Numeric inference variables may be left unresolved.
51065049 pub fn structurally_resolved_type ( & self , sp : Span , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
5107- self . structurally_resolve_type_or_else ( sp, ty, || {
5050+ let ty = self . resolve_type_vars_with_obligations ( ty) ;
5051+ if !ty. is_ty_var ( ) {
5052+ ty
5053+ } else {
5054+ if !self . is_tainted_by_errors ( ) {
5055+ type_error_struct ! ( self . tcx. sess, sp, ty, E0619 ,
5056+ "the type of this value must be known in this context" )
5057+ . emit ( ) ;
5058+ }
5059+ self . demand_suptype ( sp, self . tcx . types . err , ty) ;
51085060 self . tcx . types . err
5109- } )
5061+ }
51105062 }
51115063
51125064 fn with_breakable_ctxt < F : FnOnce ( ) -> R , R > ( & self , id : ast:: NodeId ,
0 commit comments