@@ -337,7 +337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
337
337
expected : Ty < ' tcx > ,
338
338
pat_info : PatInfo < ' tcx > ,
339
339
) {
340
- let PatInfo { binding_mode, max_ref_mutbl , top_info : ti , current_depth, .. } = pat_info;
340
+ let PatInfo { mut binding_mode, mut max_ref_mutbl , current_depth, .. } = pat_info;
341
341
#[ cfg( debug_assertions) ]
342
342
if binding_mode == ByRef :: Yes ( Mutability :: Mut )
343
343
&& max_ref_mutbl != MutblCap :: Mut
@@ -346,72 +346,76 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
346
346
span_bug ! ( pat. span, "Pattern mutability cap violated!" ) ;
347
347
}
348
348
349
- let ( expected , binding_mode , max_ref_mutbl ) = match adjust_mode {
349
+ if !pat . default_binding_modes {
350
350
// When we perform destructuring assignment, we disable default match bindings, which
351
351
// are unintuitive in this context.
352
- _ if !pat. default_binding_modes => ( expected, ByRef :: No , MutblCap :: Mut ) ,
353
- AdjustMode :: Pass => ( expected, binding_mode, max_ref_mutbl) ,
354
- // Peel an immediately nested `& mut?` from the expected type if possible and return the
355
- // new expected type and binding default binding mode.
356
- AdjustMode :: Peel => {
357
- let expected = self . try_structurally_resolve_type ( pat. span , expected) ;
358
- // Peel off a `&` or `&mut` from the scrutinee type. For each ampersand peeled off,
359
- // update the binding mode and push the original type into the adjustments vector.
360
- //
361
- // See the examples in `tests/ui/rfcs/rfc-2005-default-binding-mode`.
362
- if let ty:: Ref ( _, inner_ty, inner_mutability) = * expected. kind ( ) {
363
- debug ! ( "inspecting {:?}" , expected) ;
364
-
365
- debug ! ( "current discriminant is Ref, inserting implicit deref" ) ;
366
- // Preserve the reference type. We'll need it later during THIR lowering.
367
- self . typeck_results
368
- . borrow_mut ( )
369
- . pat_adjustments_mut ( )
370
- . entry ( pat. hir_id )
371
- . or_default ( )
372
- . push ( expected) ;
373
-
374
- let mut binding_mode = ByRef :: Yes ( match binding_mode {
375
- // If default binding mode is by value, make it `ref` or `ref mut`
376
- // (depending on whether we observe `&` or `&mut`).
377
- ByRef :: No |
378
- // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
379
- ByRef :: Yes ( Mutability :: Mut ) => inner_mutability,
380
- // Once a `ref`, always a `ref`.
381
- // This is because a `& &mut` cannot mutate the underlying value.
382
- ByRef :: Yes ( Mutability :: Not ) => Mutability :: Not ,
383
- } ) ;
384
-
385
- if self . downgrade_mut_inside_shared ( ) {
386
- binding_mode = binding_mode. cap_ref_mutability ( max_ref_mutbl. as_mutbl ( ) ) ;
387
- }
388
- let mut max_ref_mutbl = max_ref_mutbl;
389
- if binding_mode == ByRef :: Yes ( Mutability :: Not ) {
390
- max_ref_mutbl = MutblCap :: Not ;
391
- }
392
- debug ! ( "default binding mode is now {:?}" , binding_mode) ;
393
- let pat_info = PatInfo { binding_mode, max_ref_mutbl, ..pat_info } ;
394
- return self . check_pat_inner (
395
- pat,
396
- opt_path_res,
397
- adjust_mode,
398
- inner_ty,
399
- pat_info,
400
- ) ;
401
- } else {
402
- ( expected, binding_mode, max_ref_mutbl)
403
- }
404
- }
352
+ binding_mode = ByRef :: No ;
353
+ max_ref_mutbl = MutblCap :: Mut ;
354
+ } ;
355
+ // Resolve type if needed.
356
+ let expected = if let AdjustMode :: Peel = adjust_mode
357
+ && pat. default_binding_modes
358
+ {
359
+ self . try_structurally_resolve_type ( pat. span , expected)
360
+ } else {
361
+ expected
405
362
} ;
363
+ let old_pat_info = pat_info;
406
364
let pat_info = PatInfo {
407
365
binding_mode,
408
366
max_ref_mutbl,
409
- top_info : ti,
410
- decl_origin : pat_info. decl_origin ,
411
367
current_depth : current_depth + 1 ,
368
+ top_info : old_pat_info. top_info ,
369
+ decl_origin : old_pat_info. decl_origin ,
412
370
} ;
413
371
414
372
let ty = match pat. kind {
373
+ // Peel off a `&` or `&mut` from the scrutinee type. See the examples in
374
+ // `tests/ui/rfcs/rfc-2005-default-binding-mode`.
375
+ _ if let AdjustMode :: Peel = adjust_mode
376
+ && pat. default_binding_modes
377
+ && let ty:: Ref ( _, inner_ty, inner_mutability) = * expected. kind ( ) =>
378
+ {
379
+ debug ! ( "inspecting {:?}" , expected) ;
380
+
381
+ debug ! ( "current discriminant is Ref, inserting implicit deref" ) ;
382
+ // Preserve the reference type. We'll need it later during THIR lowering.
383
+ self . typeck_results
384
+ . borrow_mut ( )
385
+ . pat_adjustments_mut ( )
386
+ . entry ( pat. hir_id )
387
+ . or_default ( )
388
+ . push ( expected) ;
389
+
390
+ binding_mode = ByRef :: Yes ( match binding_mode {
391
+ // If default binding mode is by value, make it `ref` or `ref mut`
392
+ // (depending on whether we observe `&` or `&mut`).
393
+ ByRef :: No |
394
+ // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
395
+ ByRef :: Yes ( Mutability :: Mut ) => inner_mutability,
396
+ // Once a `ref`, always a `ref`.
397
+ // This is because a `& &mut` cannot mutate the underlying value.
398
+ ByRef :: Yes ( Mutability :: Not ) => Mutability :: Not ,
399
+ } ) ;
400
+
401
+ if self . downgrade_mut_inside_shared ( ) {
402
+ binding_mode = binding_mode. cap_ref_mutability ( max_ref_mutbl. as_mutbl ( ) ) ;
403
+ }
404
+ if binding_mode == ByRef :: Yes ( Mutability :: Not ) {
405
+ max_ref_mutbl = MutblCap :: Not ;
406
+ }
407
+ debug ! ( "default binding mode is now {:?}" , binding_mode) ;
408
+
409
+ // Use the old pat info to keep `current_depth` to its old value.
410
+ 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
+ ) ;
418
+ }
415
419
PatKind :: Missing | PatKind :: Wild | PatKind :: Err ( _) => expected,
416
420
// We allow any type here; we ensure that the type is uninhabited during match checking.
417
421
PatKind :: Never => expected,
0 commit comments