@@ -294,7 +294,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
294294 AdjustMode :: Pass => ( expected, def_bm, false ) ,
295295 AdjustMode :: Reset => ( expected, INITIAL_BM , false ) ,
296296 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+ }
298307 }
299308 AdjustMode :: Peel => {
300309 let peeled = self . peel_off_references ( pat, expected, def_bm) ;
@@ -2063,61 +2072,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20632072 pat_info : PatInfo < ' tcx , ' _ > ,
20642073 consumed_inherited_ref : bool ,
20652074 ) -> 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+ ) ;
21022119
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)
21082127 }
2109- ( ref_ty, inner_ty)
21102128 }
21112129 }
21122130 }
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+ }
21212139 }
21222140
21232141 /// Create a reference type with a fresh region variable.
0 commit comments