@@ -228,14 +228,10 @@ impl<'a, 'tcx> PatMigration<'a, 'tcx> {
228
228
/// This should only be called when the pattern type adjustments list `ref_tys` is non-empty.
229
229
/// This should be followed by a call to [`PatMigration::leave_ref`] when we leave the pattern.
230
230
pub ( super ) fn visit_implicit_derefs ( & mut self , pat : & hir:: Pat < ' _ > , ref_tys : & ' a [ Ty < ' tcx > ] ) {
231
- // Remember if this changed the default binding mode, in case we want to label it.
232
- let new_real_ref_mutbl = match self . real_default_mode ( ) {
233
- ByRef :: Yes ( Mutability :: Not ) => Mutability :: Not ,
234
- _ => iter_ref_mutbls ( pat. span , ref_tys) . min ( ) . unwrap ( ) ,
235
- } ;
236
- self . push_deref ( pat. span , ByRef :: Yes ( new_real_ref_mutbl) , PatDerefKind :: Implicit {
237
- ref_tys,
238
- } ) ;
231
+ let mutbl = iter_ref_mutbls ( pat. span , ref_tys)
232
+ . min ( )
233
+ . expect ( "`ref_tys` should have at least one element" ) ;
234
+ self . push_deref ( pat. span , mutbl, PatDerefKind :: Implicit { ref_tys } ) ;
239
235
}
240
236
241
237
/// Tracks the default binding mode when we're lowering a `&` or `&mut` pattern.
@@ -244,17 +240,25 @@ impl<'a, 'tcx> PatMigration<'a, 'tcx> {
244
240
// dereferences. If reference patterns can match the default binding mode alone, we may need to
245
241
// check `TypeckResults::skipped_ref_pats` to tell if this pattern corresponds to an implicit
246
242
// dereference we've already visited.
247
- pub ( super ) fn visit_explicit_deref ( & mut self , pat_span : Span ) {
243
+ pub ( super ) fn visit_explicit_deref ( & mut self , pat_span : Span , mutbl : Mutability ) {
248
244
// If this eats a by-ref default binding mode, label the binding mode.
249
245
self . add_default_mode_label_if_needed ( ) ;
250
246
// Set the default binding mode to by-value.
251
- self . push_deref ( pat_span, ByRef :: No , PatDerefKind :: Explicit ) ;
247
+ self . push_deref ( pat_span, mutbl , PatDerefKind :: Explicit ) ;
252
248
}
253
249
254
250
/// Adds a deref to our deref-forest, so that we can track the default binding mode.
255
251
// TODO: this is also for propagating binding mode changes when we suggest adding patterns
256
- fn push_deref ( & mut self , span : Span , real_default_mode : ByRef , kind : PatDerefKind < ' a , ' tcx > ) {
252
+ fn push_deref ( & mut self , span : Span , mutbl : Mutability , kind : PatDerefKind < ' a , ' tcx > ) {
257
253
let parent = self . innermost_deref ;
254
+ // Get the new default binding mode in the pattern the user wrote.
255
+ let real_default_mode = match kind {
256
+ PatDerefKind :: Implicit { .. } => match self . real_default_mode ( ) {
257
+ ByRef :: Yes ( old_mutbl) => ByRef :: Yes ( Ord :: min ( mutbl, old_mutbl) ) ,
258
+ ByRef :: No => ByRef :: Yes ( mutbl) ,
259
+ } ,
260
+ PatDerefKind :: Explicit => ByRef :: No ,
261
+ } ;
258
262
// If this keeps the default binding mode the same, it shares a mode origin with its
259
263
// parent. If it changes the default binding mode, its mode origin is itself.
260
264
let default_mode_origin = if real_default_mode == self . real_default_mode ( ) {
0 commit comments