@@ -1293,9 +1293,11 @@ fn check_fn<'a, 'tcx>(
1293
1293
} ;
1294
1294
1295
1295
// Add formal parameters.
1296
- for ( param_ty, param) in fn_sig. inputs ( ) . iter ( ) . copied ( ) . chain ( maybe_va_list) . zip ( body. params ) {
1296
+ let inputs_hir = hir. fn_decl_by_hir_id ( fn_id) . map ( |decl| & decl. inputs ) ;
1297
+ let inputs_fn = fn_sig. inputs ( ) . iter ( ) . copied ( ) ;
1298
+ for ( idx, ( param_ty, param) ) in inputs_fn. chain ( maybe_va_list) . zip ( body. params ) . enumerate ( ) {
1297
1299
// Check the pattern.
1298
- fcx. check_pat_top ( & param. pat , param_ty, None ) ;
1300
+ fcx. check_pat_top ( & param. pat , param_ty, try { inputs_hir? . get ( idx ) ? . span } , false ) ;
1299
1301
1300
1302
// Check that argument is Sized.
1301
1303
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
@@ -4276,16 +4278,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4276
4278
}
4277
4279
}
4278
4280
4281
+ /// Type check a `let` statement.
4279
4282
pub fn check_decl_local ( & self , local : & ' tcx hir:: Local < ' tcx > ) {
4283
+ // Determine and write the type which we'll check the pattern against.
4280
4284
let ty = self . local_ty ( local. span , local. hir_id ) . decl_ty ;
4281
4285
self . write_ty ( local. hir_id , ty) ;
4282
4286
4287
+ // Type check the initializer.
4283
4288
if let Some ( ref init) = local. init {
4284
4289
let init_ty = self . check_decl_initializer ( local, & init) ;
4285
4290
self . overwrite_local_ty_if_err ( local, ty, init_ty) ;
4286
4291
}
4287
4292
4288
- self . check_pat_top ( & local. pat , ty, local. init . map ( |init| init. span ) ) ;
4293
+ // Does the expected pattern type originate from an expression and what is the span?
4294
+ let ( origin_expr, ty_span) = match ( local. ty , local. init ) {
4295
+ ( Some ( ty) , _) => ( false , Some ( ty. span ) ) , // Bias towards the explicit user type.
4296
+ ( _, Some ( init) ) => ( true , Some ( init. span ) ) , // No explicit type; so use the scrutinee.
4297
+ _ => ( false , None ) , // We have `let $pat;`, so the expected type is unconstrained.
4298
+ } ;
4299
+
4300
+ // Type check the pattern. Override if necessary to avoid knock-on errors.
4301
+ self . check_pat_top ( & local. pat , ty, ty_span, origin_expr) ;
4289
4302
let pat_ty = self . node_ty ( local. pat . hir_id ) ;
4290
4303
self . overwrite_local_ty_if_err ( local, ty, pat_ty) ;
4291
4304
}
@@ -4297,7 +4310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4297
4310
ty : Ty < ' tcx > ,
4298
4311
) {
4299
4312
if ty. references_error ( ) {
4300
- // Override the types everywhere with `types.err` to avoid knock down errors.
4313
+ // Override the types everywhere with `types.err` to avoid knock on errors.
4301
4314
self . write_ty ( local. hir_id , ty) ;
4302
4315
self . write_ty ( local. pat . hir_id , ty) ;
4303
4316
let local_ty = LocalTy { decl_ty, revealed_ty : ty } ;
0 commit comments