@@ -1293,9 +1293,11 @@ fn check_fn<'a, 'tcx>(
12931293 } ;
12941294
12951295 // 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 ( ) {
12971299 // 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 ) ;
12991301
13001302 // Check that argument is Sized.
13011303 // The check for a non-trivial pattern is a hack to avoid duplicate warnings
@@ -4276,16 +4278,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
42764278 }
42774279 }
42784280
4281+ /// Type check a `let` statement.
42794282 pub fn check_decl_local ( & self , local : & ' tcx hir:: Local < ' tcx > ) {
4283+ // Determine and write the type which we'll check the pattern against.
42804284 let ty = self . local_ty ( local. span , local. hir_id ) . decl_ty ;
42814285 self . write_ty ( local. hir_id , ty) ;
42824286
4287+ // Type check the initializer.
42834288 if let Some ( ref init) = local. init {
42844289 let init_ty = self . check_decl_initializer ( local, & init) ;
42854290 self . overwrite_local_ty_if_err ( local, ty, init_ty) ;
42864291 }
42874292
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) ;
42894302 let pat_ty = self . node_ty ( local. pat . hir_id ) ;
42904303 self . overwrite_local_ty_if_err ( local, ty, pat_ty) ;
42914304 }
@@ -4297,7 +4310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
42974310 ty : Ty < ' tcx > ,
42984311 ) {
42994312 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.
43014314 self . write_ty ( local. hir_id , ty) ;
43024315 self . write_ty ( local. pat . hir_id , ty) ;
43034316 let local_ty = LocalTy { decl_ty, revealed_ty : ty } ;
0 commit comments