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