@@ -325,7 +325,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
325
325
_ => None ,
326
326
} ;
327
327
let adjust_mode = self . calc_adjust_mode ( pat, opt_path_res. map ( |( res, ..) | res) ) ;
328
- self . check_pat_inner ( pat, opt_path_res, adjust_mode, expected, pat_info) ;
328
+ let ty = self . check_pat_inner ( pat, opt_path_res, adjust_mode, expected, pat_info) ;
329
+ self . write_ty ( pat. hir_id , ty) ;
330
+
331
+ // (note_1): In most of the cases where (note_1) is referenced
332
+ // (literals and constants being the exception), we relate types
333
+ // using strict equality, even though subtyping would be sufficient.
334
+ // There are a few reasons for this, some of which are fairly subtle
335
+ // and which cost me (nmatsakis) an hour or two debugging to remember,
336
+ // so I thought I'd write them down this time.
337
+ //
338
+ // 1. There is no loss of expressiveness here, though it does
339
+ // cause some inconvenience. What we are saying is that the type
340
+ // of `x` becomes *exactly* what is expected. This can cause unnecessary
341
+ // errors in some cases, such as this one:
342
+ //
343
+ // ```
344
+ // fn foo<'x>(x: &'x i32) {
345
+ // let a = 1;
346
+ // let mut z = x;
347
+ // z = &a;
348
+ // }
349
+ // ```
350
+ //
351
+ // The reason we might get an error is that `z` might be
352
+ // assigned a type like `&'x i32`, and then we would have
353
+ // a problem when we try to assign `&a` to `z`, because
354
+ // the lifetime of `&a` (i.e., the enclosing block) is
355
+ // shorter than `'x`.
356
+ //
357
+ // HOWEVER, this code works fine. The reason is that the
358
+ // expected type here is whatever type the user wrote, not
359
+ // the initializer's type. In this case the user wrote
360
+ // nothing, so we are going to create a type variable `Z`.
361
+ // Then we will assign the type of the initializer (`&'x i32`)
362
+ // as a subtype of `Z`: `&'x i32 <: Z`. And hence we
363
+ // will instantiate `Z` as a type `&'0 i32` where `'0` is
364
+ // a fresh region variable, with the constraint that `'x : '0`.
365
+ // So basically we're all set.
366
+ //
367
+ // Note that there are two tests to check that this remains true
368
+ // (`regions-reassign-{match,let}-bound-pointer.rs`).
369
+ //
370
+ // 2. An outdated issue related to the old HIR borrowck. See the test
371
+ // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
329
372
}
330
373
331
374
// Helper to avoid resolving the same path pattern several times.
@@ -336,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
336
379
adjust_mode : AdjustMode ,
337
380
expected : Ty < ' tcx > ,
338
381
pat_info : PatInfo < ' tcx > ,
339
- ) {
382
+ ) -> Ty < ' tcx > {
340
383
let PatInfo { mut binding_mode, mut max_ref_mutbl, current_depth, .. } = pat_info;
341
384
#[ cfg( debug_assertions) ]
342
385
if binding_mode == ByRef :: Yes ( Mutability :: Mut )
@@ -369,7 +412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
369
412
decl_origin : old_pat_info. decl_origin ,
370
413
} ;
371
414
372
- let ty = match pat. kind {
415
+ match pat. kind {
373
416
// Peel off a `&` or `&mut` from the scrutinee type. See the examples in
374
417
// `tests/ui/rfcs/rfc-2005-default-binding-mode`.
375
418
_ if let AdjustMode :: Peel = adjust_mode
@@ -408,13 +451,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
408
451
409
452
// Use the old pat info to keep `current_depth` to its old value.
410
453
let new_pat_info = PatInfo { binding_mode, max_ref_mutbl, ..old_pat_info } ;
411
- return self . check_pat_inner (
412
- pat,
413
- opt_path_res,
414
- adjust_mode,
415
- inner_ty,
416
- new_pat_info,
417
- ) ;
454
+ // Recurse with the new expected type.
455
+ self . check_pat_inner ( pat, opt_path_res, adjust_mode, inner_ty, new_pat_info)
418
456
}
419
457
PatKind :: Missing | PatKind :: Wild | PatKind :: Err ( _) => expected,
420
458
// We allow any type here; we ensure that the type is uninhabited during match checking.
@@ -465,51 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
465
503
PatKind :: Slice ( before, slice, after) => {
466
504
self . check_pat_slice ( pat. span , before, slice, after, expected, pat_info)
467
505
}
468
- } ;
469
-
470
- self . write_ty ( pat. hir_id , ty) ;
471
-
472
- // (note_1): In most of the cases where (note_1) is referenced
473
- // (literals and constants being the exception), we relate types
474
- // using strict equality, even though subtyping would be sufficient.
475
- // There are a few reasons for this, some of which are fairly subtle
476
- // and which cost me (nmatsakis) an hour or two debugging to remember,
477
- // so I thought I'd write them down this time.
478
- //
479
- // 1. There is no loss of expressiveness here, though it does
480
- // cause some inconvenience. What we are saying is that the type
481
- // of `x` becomes *exactly* what is expected. This can cause unnecessary
482
- // errors in some cases, such as this one:
483
- //
484
- // ```
485
- // fn foo<'x>(x: &'x i32) {
486
- // let a = 1;
487
- // let mut z = x;
488
- // z = &a;
489
- // }
490
- // ```
491
- //
492
- // The reason we might get an error is that `z` might be
493
- // assigned a type like `&'x i32`, and then we would have
494
- // a problem when we try to assign `&a` to `z`, because
495
- // the lifetime of `&a` (i.e., the enclosing block) is
496
- // shorter than `'x`.
497
- //
498
- // HOWEVER, this code works fine. The reason is that the
499
- // expected type here is whatever type the user wrote, not
500
- // the initializer's type. In this case the user wrote
501
- // nothing, so we are going to create a type variable `Z`.
502
- // Then we will assign the type of the initializer (`&'x i32`)
503
- // as a subtype of `Z`: `&'x i32 <: Z`. And hence we
504
- // will instantiate `Z` as a type `&'0 i32` where `'0` is
505
- // a fresh region variable, with the constraint that `'x : '0`.
506
- // So basically we're all set.
507
- //
508
- // Note that there are two tests to check that this remains true
509
- // (`regions-reassign-{match,let}-bound-pointer.rs`).
510
- //
511
- // 2. An outdated issue related to the old HIR borrowck. See the test
512
- // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
506
+ }
513
507
}
514
508
515
509
/// How should the binding mode and expected type be adjusted?
0 commit comments