@@ -871,10 +871,21 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
871
871
fcx
872
872
} ;
873
873
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
+ }
876
879
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.
877
883
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( ) ) ;
878
889
fcx. resolve_generator_interiors ( def_id) ;
879
890
fcx. select_all_obligations_or_error ( ) ;
880
891
@@ -2143,74 +2154,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2143
2154
}
2144
2155
}
2145
2156
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 > ) {
2151
2164
use rustc:: ty:: error:: UnconstrainedNumeric :: Neither ;
2152
2165
use rustc:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedInt , UnconstrainedFloat } ;
2153
2166
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) ;
2198
2177
}
2199
2178
2200
2179
fn select_all_obligations_or_error ( & self ) {
2201
2180
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 ) ;
2214
2183
}
2215
2184
}
2216
2185
@@ -5074,39 +5043,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5074
5043
} ) ;
5075
5044
}
5076
5045
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.
5106
5049
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) ;
5108
5060
self . tcx . types . err
5109
- } )
5061
+ }
5110
5062
}
5111
5063
5112
5064
fn with_breakable_ctxt < F : FnOnce ( ) -> R , R > ( & self , id : ast:: NodeId ,
0 commit comments