@@ -25,7 +25,9 @@ use syntax::ast::RangeOp;
25
25
use crate :: {
26
26
autoderef:: { self , Autoderef } ,
27
27
consteval,
28
- infer:: { coerce:: CoerceMany , find_continuable, BreakableKind } ,
28
+ infer:: {
29
+ coerce:: CoerceMany , find_continuable, pat:: contains_explicit_ref_binding, BreakableKind ,
30
+ } ,
29
31
lower:: {
30
32
const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode ,
31
33
} ,
@@ -39,8 +41,8 @@ use crate::{
39
41
} ;
40
42
41
43
use super :: {
42
- coerce:: auto_deref_adjust_steps, find_breakable, BindingMode , BreakableContext , Diverges ,
43
- Expectation , InferenceContext , InferenceDiagnostic , TypeMismatch ,
44
+ coerce:: auto_deref_adjust_steps, find_breakable, BreakableContext , Diverges , Expectation ,
45
+ InferenceContext , InferenceDiagnostic , TypeMismatch ,
44
46
} ;
45
47
46
48
impl < ' a > InferenceContext < ' a > {
@@ -111,7 +113,7 @@ impl<'a> InferenceContext<'a> {
111
113
}
112
114
& Expr :: Let { pat, expr } => {
113
115
let input_ty = self . infer_expr ( expr, & Expectation :: none ( ) ) ;
114
- self . infer_pat ( pat, & input_ty, BindingMode :: default ( ) ) ;
116
+ self . infer_top_pat ( pat, & input_ty) ;
115
117
self . result . standard_types . bool_ . clone ( )
116
118
}
117
119
Expr :: Block { statements, tail, label, id : _ } => {
@@ -223,7 +225,7 @@ impl<'a> InferenceContext<'a> {
223
225
let pat_ty =
224
226
self . resolve_associated_type ( into_iter_ty, self . resolve_iterator_item ( ) ) ;
225
227
226
- self . infer_pat ( pat, & pat_ty, BindingMode :: default ( ) ) ;
228
+ self . infer_top_pat ( pat, & pat_ty) ;
227
229
self . with_breakable_ctx ( BreakableKind :: Loop , self . err_ty ( ) , label, |this| {
228
230
this. infer_expr ( body, & Expectation :: HasType ( TyBuilder :: unit ( ) ) ) ;
229
231
} ) ;
@@ -298,7 +300,7 @@ impl<'a> InferenceContext<'a> {
298
300
299
301
// Now go through the argument patterns
300
302
for ( arg_pat, arg_ty) in args. iter ( ) . zip ( sig_tys) {
301
- self . infer_pat ( * arg_pat, & arg_ty, BindingMode :: default ( ) ) ;
303
+ self . infer_top_pat ( * arg_pat, & arg_ty) ;
302
304
}
303
305
304
306
let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
@@ -395,7 +397,8 @@ impl<'a> InferenceContext<'a> {
395
397
396
398
for arm in arms. iter ( ) {
397
399
self . diverges = Diverges :: Maybe ;
398
- let _pat_ty = self . infer_pat ( arm. pat , & input_ty, BindingMode :: default ( ) ) ;
400
+ let input_ty = self . resolve_ty_shallow ( & input_ty) ;
401
+ let _pat_ty = self . infer_top_pat ( arm. pat , & input_ty) ;
399
402
if let Some ( guard_expr) = arm. guard {
400
403
self . infer_expr (
401
404
guard_expr,
@@ -1142,27 +1145,33 @@ impl<'a> InferenceContext<'a> {
1142
1145
let decl_ty = type_ref
1143
1146
. as_ref ( )
1144
1147
. map ( |tr| self . make_ty ( tr) )
1145
- . unwrap_or_else ( || self . err_ty ( ) ) ;
1146
-
1147
- // Always use the declared type when specified
1148
- let mut ty = decl_ty. clone ( ) ;
1148
+ . unwrap_or_else ( || self . table . new_type_var ( ) ) ;
1149
1149
1150
- if let Some ( expr) = initializer {
1151
- let actual_ty =
1152
- self . infer_expr_coerce ( * expr, & Expectation :: has_type ( decl_ty. clone ( ) ) ) ;
1153
- if decl_ty. is_unknown ( ) {
1154
- ty = actual_ty;
1150
+ let ty = if let Some ( expr) = initializer {
1151
+ let ty = if contains_explicit_ref_binding ( & self . body , * pat) {
1152
+ self . infer_expr ( * expr, & Expectation :: has_type ( decl_ty. clone ( ) ) )
1153
+ } else {
1154
+ self . infer_expr_coerce ( * expr, & Expectation :: has_type ( decl_ty. clone ( ) ) )
1155
+ } ;
1156
+ if type_ref. is_some ( ) {
1157
+ decl_ty
1158
+ } else {
1159
+ ty
1155
1160
}
1156
- }
1161
+ } else {
1162
+ decl_ty
1163
+ } ;
1164
+
1165
+ self . infer_top_pat ( * pat, & ty) ;
1157
1166
1158
1167
if let Some ( expr) = else_branch {
1168
+ let previous_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
1159
1169
self . infer_expr_coerce (
1160
1170
* expr,
1161
1171
& Expectation :: HasType ( self . result . standard_types . never . clone ( ) ) ,
1162
1172
) ;
1173
+ self . diverges = previous_diverges;
1163
1174
}
1164
-
1165
- self . infer_pat ( * pat, & ty, BindingMode :: default ( ) ) ;
1166
1175
}
1167
1176
Statement :: Expr { expr, .. } => {
1168
1177
self . infer_expr ( * expr, & Expectation :: none ( ) ) ;
0 commit comments