@@ -292,7 +292,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
292
292
match adjust_mode {
293
293
AdjustMode :: Pass => ( expected, def_bm, false ) ,
294
294
AdjustMode :: Reset => ( expected, INITIAL_BM , false ) ,
295
- AdjustMode :: RefReset ( mutbl) => ( expected, INITIAL_BM , def_bm. 0 == ByRef :: Yes ( mutbl) ) ,
295
+ AdjustMode :: RefReset ( mutbl) => {
296
+ let mutbls_match = def_bm. 0 == ByRef :: Yes ( mutbl) ;
297
+ if pat. span . at_least_rust_2024 ( ) && self . tcx . features ( ) . and_eat_one_layer_2024 {
298
+ if mutbls_match {
299
+ ( expected, INITIAL_BM , true )
300
+ } else {
301
+ ( expected, def_bm, false )
302
+ }
303
+ } else {
304
+ ( expected, INITIAL_BM , mutbls_match)
305
+ }
306
+ }
296
307
AdjustMode :: Peel => {
297
308
let peeled = self . peel_off_references ( pat, expected, def_bm) ;
298
309
( peeled. 0 , peeled. 1 , false )
@@ -2060,61 +2071,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2060
2071
pat_info : PatInfo < ' tcx , ' _ > ,
2061
2072
already_consumed : bool ,
2062
2073
) -> Ty < ' tcx > {
2063
- let tcx = self . tcx ;
2064
- let expected = self . shallow_resolve ( expected) ;
2065
- let ( ref_ty, inner_ty) = match self . check_dereferenceable ( pat. span , expected, inner) {
2066
- Ok ( ( ) ) => {
2067
- // `demand::subtype` would be good enough, but using `eqtype` turns
2068
- // out to be equally general. See (note_1) for details.
2069
-
2070
- // Take region, inner-type from expected type if we can,
2071
- // to avoid creating needless variables. This also helps with
2072
- // the bad interactions of the given hack detailed in (note_1).
2073
- debug ! ( "check_pat_ref: expected={:?}" , expected) ;
2074
- match * expected. kind ( ) {
2075
- ty:: Ref ( _, r_ty, r_mutbl) if r_mutbl == mutbl => ( expected, r_ty) ,
2076
- _ => {
2077
- if already_consumed && self . tcx . features ( ) . and_pat_everywhere {
2078
- // We already matched against a match-ergonmics inserted reference,
2079
- // so we don't need to match against a reference from the original type.
2080
- // Save this infor for use in lowering later
2081
- self . typeck_results
2082
- . borrow_mut ( )
2083
- . ref_pats_that_dont_deref_mut ( )
2084
- . insert ( pat. hir_id ) ;
2085
- ( expected, expected)
2086
- } else {
2087
- let inner_ty = self . next_ty_var ( TypeVariableOrigin {
2088
- kind : TypeVariableOriginKind :: TypeInference ,
2089
- span : inner. span ,
2090
- } ) ;
2091
- let ref_ty = self . new_ref_ty ( pat. span , mutbl, inner_ty) ;
2092
- debug ! ( "check_pat_ref: demanding {:?} = {:?}" , expected, ref_ty) ;
2093
- let err = self . demand_eqtype_pat_diag (
2094
- pat. span ,
2095
- expected,
2096
- ref_ty,
2097
- pat_info. top_info ,
2098
- ) ;
2074
+ if already_consumed
2075
+ && pat. span . at_least_rust_2024 ( )
2076
+ && self . tcx . features ( ) . and_eat_one_layer_2024
2077
+ {
2078
+ self . typeck_results . borrow_mut ( ) . ref_pats_that_dont_deref_mut ( ) . insert ( pat. hir_id ) ;
2079
+ self . check_pat ( inner, expected, pat_info) ;
2080
+ expected
2081
+ } else {
2082
+ let tcx = self . tcx ;
2083
+ let expected = self . shallow_resolve ( expected) ;
2084
+ let ( ref_ty, inner_ty) = match self . check_dereferenceable ( pat. span , expected, inner) {
2085
+ Ok ( ( ) ) => {
2086
+ // `demand::subtype` would be good enough, but using `eqtype` turns
2087
+ // out to be equally general. See (note_1) for details.
2088
+
2089
+ // Take region, inner-type from expected type if we can,
2090
+ // to avoid creating needless variables. This also helps with
2091
+ // the bad interactions of the given hack detailed in (note_1).
2092
+ debug ! ( "check_pat_ref: expected={:?}" , expected) ;
2093
+ match * expected. kind ( ) {
2094
+ ty:: Ref ( _, r_ty, r_mutbl) if r_mutbl == mutbl => ( expected, r_ty) ,
2095
+ _ => {
2096
+ if already_consumed && self . tcx . features ( ) . and_pat_everywhere {
2097
+ // We already matched against a match-ergonmics inserted reference,
2098
+ // so we don't need to match against a reference from the original type.
2099
+ // Save this infor for use in lowering later
2100
+ self . typeck_results
2101
+ . borrow_mut ( )
2102
+ . ref_pats_that_dont_deref_mut ( )
2103
+ . insert ( pat. hir_id ) ;
2104
+ ( expected, expected)
2105
+ } else {
2106
+ let inner_ty = self . next_ty_var ( TypeVariableOrigin {
2107
+ kind : TypeVariableOriginKind :: TypeInference ,
2108
+ span : inner. span ,
2109
+ } ) ;
2110
+ let ref_ty = self . new_ref_ty ( pat. span , mutbl, inner_ty) ;
2111
+ debug ! ( "check_pat_ref: demanding {:?} = {:?}" , expected, ref_ty) ;
2112
+ let err = self . demand_eqtype_pat_diag (
2113
+ pat. span ,
2114
+ expected,
2115
+ ref_ty,
2116
+ pat_info. top_info ,
2117
+ ) ;
2099
2118
2100
- // Look for a case like `fn foo(&foo: u32)` and suggest
2101
- // `fn foo(foo: &u32)`
2102
- if let Some ( mut err) = err {
2103
- self . borrow_pat_suggestion ( & mut err, pat) ;
2104
- err. emit ( ) ;
2119
+ // Look for a case like `fn foo(&foo: u32)` and suggest
2120
+ // `fn foo(foo: &u32)`
2121
+ if let Some ( mut err) = err {
2122
+ self . borrow_pat_suggestion ( & mut err, pat) ;
2123
+ err. emit ( ) ;
2124
+ }
2125
+ ( ref_ty, inner_ty)
2105
2126
}
2106
- ( ref_ty, inner_ty)
2107
2127
}
2108
2128
}
2109
2129
}
2110
- }
2111
- Err ( guar ) => {
2112
- let err = Ty :: new_error ( tcx , guar ) ;
2113
- ( err , err )
2114
- }
2115
- } ;
2116
- self . check_pat ( inner , inner_ty , pat_info ) ;
2117
- ref_ty
2130
+ Err ( guar ) => {
2131
+ let err = Ty :: new_error ( tcx , guar ) ;
2132
+ ( err , err )
2133
+ }
2134
+ } ;
2135
+ self . check_pat ( inner , inner_ty , pat_info ) ;
2136
+ ref_ty
2137
+ }
2118
2138
}
2119
2139
2120
2140
/// Create a reference type with a fresh region variable.
0 commit comments