Skip to content

Commit 0c430f7

Browse files
Match ergonomics 2024: Implement eat-one-layer
1 parent 1921968 commit 0c430f7

14 files changed

+660
-51
lines changed

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ declare_features! (
567567
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
568568
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
569569
(unstable, raw_ref_op, "1.41.0", Some(64490)),
570+
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
571+
(incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)),
570572
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
571573
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
572574
/// Allows using the `#[register_tool]` attribute.

compiler/rustc_hir_typeck/src/pat.rs

+69-51
Original file line numberDiff line numberDiff line change
@@ -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.

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,7 @@ symbols! {
14561456
receiver,
14571457
recursion_limit,
14581458
reexport_test_harness_main,
1459+
ref_pat_eat_one_layer_2024,
14591460
ref_pat_everywhere,
14601461
ref_unwind_safe_trait,
14611462
reference,
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
thread 'rustc' panicked at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/compiler/rustc_query_system/src/dep_graph/serialized.rs:190:9:
2+
assertion `left == right` failed
3+
left: 2748068
4+
right: 483822093627794247
5+
stack backtrace:
6+
0: 0x7fe23ae3830f - std::backtrace_rs::backtrace::libunwind::trace::h539c03b0789a3163
7+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/../../backtrace/src/backtrace/libunwind.rs:105:5
8+
1: 0x7fe23ae3830f - std::backtrace_rs::backtrace::trace_unsynchronized::h90a51b49b444fc01
9+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
10+
2: 0x7fe23ae3830f - std::backtrace::Backtrace::create::h52a6c1d2ae0a3112
11+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/backtrace.rs:331:13
12+
3: 0x7fe23ae38250 - std::backtrace::Backtrace::force_capture::h70557b27472ed963
13+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/backtrace.rs:312:9
14+
4: 0x7fe237a2ccb7 - std[999bdecce25602ed]::panicking::update_hook::<alloc[5d2a9fe8278cb303]::boxed::Box<rustc_driver_impl[e6c4295f52574c92]::install_ice_hook::{closure#0}>>::{closure#0}
15+
5: 0x7fe23ae52b50 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h8e05c89c9dfd827c
16+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/alloc/src/boxed.rs:2034:9
17+
6: 0x7fe23ae52b50 - std::panicking::rust_panic_with_hook::h6987b578e7dec23c
18+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/panicking.rs:783:13
19+
7: 0x7fe23ae52892 - std::panicking::begin_panic_handler::{{closure}}::h5e61050e5431c199
20+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/panicking.rs:657:13
21+
8: 0x7fe23ae4fde6 - std::sys_common::backtrace::__rust_end_short_backtrace::h19cdae527db4e43c
22+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/sys_common/backtrace.rs:171:18
23+
9: 0x7fe23ae525c4 - rust_begin_unwind
24+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/panicking.rs:645:5
25+
10: 0x7fe23ae9d1a5 - core::panicking::panic_fmt::h18a3c8b0a37e1072
26+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/core/src/panicking.rs:72:14
27+
11: 0x7fe23ae9d6eb - core::panicking::assert_failed_inner::hd0e0d1dad5c19ba3
28+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/core/src/panicking.rs:343:17
29+
12: 0x7fe237c54413 - core[75bed1c93f3984e1]::panicking::assert_failed::<usize, usize>
30+
13: 0x7fe239a11172 - rustc_incremental[fcd664b986d92611]::persist::load::setup_dep_graph
31+
14: 0x7fe23996d683 - <rustc_interface[2cd87b402a7bbb07]::queries::Queries>::global_ctxt
32+
15: 0x7fe2397a56c0 - rustc_interface[2cd87b402a7bbb07]::interface::run_compiler::<core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>, rustc_driver_impl[e6c4295f52574c92]::run_compiler::{closure#0}>::{closure#0}
33+
16: 0x7fe239ab1b2e - std[999bdecce25602ed]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[2cd87b402a7bbb07]::util::run_in_thread_with_globals<rustc_interface[2cd87b402a7bbb07]::interface::run_compiler<core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>, rustc_driver_impl[e6c4295f52574c92]::run_compiler::{closure#0}>::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>
34+
17: 0x7fe239ab198a - <<std[999bdecce25602ed]::thread::Builder>::spawn_unchecked_<rustc_interface[2cd87b402a7bbb07]::util::run_in_thread_with_globals<rustc_interface[2cd87b402a7bbb07]::interface::run_compiler<core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>, rustc_driver_impl[e6c4295f52574c92]::run_compiler::{closure#0}>::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>::{closure#1} as core[75bed1c93f3984e1]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
35+
18: 0x7fe23ae5c1e5 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h3b366b3d6b556d67
36+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/alloc/src/boxed.rs:2020:9
37+
19: 0x7fe23ae5c1e5 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h49756348eb63eea1
38+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/alloc/src/boxed.rs:2020:9
39+
20: 0x7fe23ae5c1e5 - std::sys::pal::unix::thread::Thread::new::thread_start::hdf802a7c2e3fdf20
40+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/sys/pal/unix/thread.rs:108:17
41+
21: 0x7fe23ac0a897 - start_thread
42+
22: 0x7fe23ac91a5c - __clone3
43+
23: 0x0 - <unknown>
44+
45+
46+
rustc version: 1.78.0-beta.1 (efd9d2df1 2024-03-18)
47+
platform: x86_64-unknown-linux-gnu
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
thread 'rustc' panicked at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/compiler/rustc_query_system/src/dep_graph/serialized.rs:190:9:
2+
assertion `left == right` failed
3+
left: 2715449
4+
right: 17419488159501254033
5+
stack backtrace:
6+
0: 0x7efca7f9630f - std::backtrace_rs::backtrace::libunwind::trace::h539c03b0789a3163
7+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/../../backtrace/src/backtrace/libunwind.rs:105:5
8+
1: 0x7efca7f9630f - std::backtrace_rs::backtrace::trace_unsynchronized::h90a51b49b444fc01
9+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
10+
2: 0x7efca7f9630f - std::backtrace::Backtrace::create::h52a6c1d2ae0a3112
11+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/backtrace.rs:331:13
12+
3: 0x7efca7f96250 - std::backtrace::Backtrace::force_capture::h70557b27472ed963
13+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/backtrace.rs:312:9
14+
4: 0x7efca4c2ccb7 - std[999bdecce25602ed]::panicking::update_hook::<alloc[5d2a9fe8278cb303]::boxed::Box<rustc_driver_impl[e6c4295f52574c92]::install_ice_hook::{closure#0}>>::{closure#0}
15+
5: 0x7efca7fb0b50 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h8e05c89c9dfd827c
16+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/alloc/src/boxed.rs:2034:9
17+
6: 0x7efca7fb0b50 - std::panicking::rust_panic_with_hook::h6987b578e7dec23c
18+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/panicking.rs:783:13
19+
7: 0x7efca7fb0892 - std::panicking::begin_panic_handler::{{closure}}::h5e61050e5431c199
20+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/panicking.rs:657:13
21+
8: 0x7efca7fadde6 - std::sys_common::backtrace::__rust_end_short_backtrace::h19cdae527db4e43c
22+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/sys_common/backtrace.rs:171:18
23+
9: 0x7efca7fb05c4 - rust_begin_unwind
24+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/panicking.rs:645:5
25+
10: 0x7efca7ffb1a5 - core::panicking::panic_fmt::h18a3c8b0a37e1072
26+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/core/src/panicking.rs:72:14
27+
11: 0x7efca7ffb6eb - core::panicking::assert_failed_inner::hd0e0d1dad5c19ba3
28+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/core/src/panicking.rs:343:17
29+
12: 0x7efca4e54413 - core[75bed1c93f3984e1]::panicking::assert_failed::<usize, usize>
30+
13: 0x7efca6c11172 - rustc_incremental[fcd664b986d92611]::persist::load::setup_dep_graph
31+
14: 0x7efca6b6d683 - <rustc_interface[2cd87b402a7bbb07]::queries::Queries>::global_ctxt
32+
15: 0x7efca69a56c0 - rustc_interface[2cd87b402a7bbb07]::interface::run_compiler::<core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>, rustc_driver_impl[e6c4295f52574c92]::run_compiler::{closure#0}>::{closure#0}
33+
16: 0x7efca6cb1b2e - std[999bdecce25602ed]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[2cd87b402a7bbb07]::util::run_in_thread_with_globals<rustc_interface[2cd87b402a7bbb07]::interface::run_compiler<core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>, rustc_driver_impl[e6c4295f52574c92]::run_compiler::{closure#0}>::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>
34+
17: 0x7efca6cb198a - <<std[999bdecce25602ed]::thread::Builder>::spawn_unchecked_<rustc_interface[2cd87b402a7bbb07]::util::run_in_thread_with_globals<rustc_interface[2cd87b402a7bbb07]::interface::run_compiler<core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>, rustc_driver_impl[e6c4295f52574c92]::run_compiler::{closure#0}>::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[75bed1c93f3984e1]::result::Result<(), rustc_span[ebf54beea9088bcf]::ErrorGuaranteed>>::{closure#1} as core[75bed1c93f3984e1]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
35+
18: 0x7efca7fba1e5 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h3b366b3d6b556d67
36+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/alloc/src/boxed.rs:2020:9
37+
19: 0x7efca7fba1e5 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h49756348eb63eea1
38+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/alloc/src/boxed.rs:2020:9
39+
20: 0x7efca7fba1e5 - std::sys::pal::unix::thread::Thread::new::thread_start::hdf802a7c2e3fdf20
40+
at /rustc/efd9d2df12b5e17fac0b4d0fb89f612ecd79f259/library/std/src/sys/pal/unix/thread.rs:108:17
41+
21: 0x7efca7d68897 - start_thread
42+
22: 0x7efca7defa5c - __clone3
43+
23: 0x0 - <unknown>
44+
45+
46+
rustc version: 1.78.0-beta.1 (efd9d2df1 2024-03-18)
47+
platform: x86_64-unknown-linux-gnu

0 commit comments

Comments
 (0)