Skip to content

Commit 9d200f2

Browse files
Address review comments
1 parent f37a4d5 commit 9d200f2

File tree

11 files changed

+55
-33
lines changed

11 files changed

+55
-33
lines changed

compiler/rustc_feature/src/unstable.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,6 @@ declare_features! (
339339
(incomplete, adt_const_params, "1.56.0", Some(95174)),
340340
/// Allows defining an `#[alloc_error_handler]`.
341341
(unstable, alloc_error_handler, "1.29.0", Some(51540)),
342-
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
343-
(incomplete, and_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
344342
/// Allows trait methods with arbitrary self types.
345343
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
346344
/// Allows using `const` operands in inline assembly.
@@ -569,6 +567,8 @@ declare_features! (
569567
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
570568
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
571569
(unstable, raw_ref_op, "1.41.0", Some(64490)),
570+
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
571+
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
572572
/// Allows using the `#[register_tool]` attribute.
573573
(unstable, register_tool, "1.41.0", Some(66079)),
574574
/// Allows the `#[repr(i128)]` attribute for enums.

compiler/rustc_hir_typeck/src/pat.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2058,7 +2058,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20582058
mutbl: Mutability,
20592059
expected: Ty<'tcx>,
20602060
pat_info: PatInfo<'tcx, '_>,
2061-
already_consumed: bool,
2061+
consumed_inherited_ref: bool,
20622062
) -> Ty<'tcx> {
20632063
let tcx = self.tcx;
20642064
let expected = self.shallow_resolve(expected);
@@ -2074,13 +2074,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20742074
match *expected.kind() {
20752075
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
20762076
_ => {
2077-
if already_consumed && self.tcx.features().and_pat_everywhere {
2077+
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
20782078
// We already matched against a match-ergonmics inserted reference,
20792079
// so we don't need to match against a reference from the original type.
20802080
// Save this infor for use in lowering later
20812081
self.typeck_results
20822082
.borrow_mut()
2083-
.ref_pats_that_dont_deref_mut()
2083+
.skipped_ref_pats_mut()
20842084
.insert(pat.hir_id);
20852085
(expected, expected)
20862086
} else {

compiler/rustc_hir_typeck/src/writeback.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
345345
_ => {}
346346
};
347347

348-
self.visit_ref_pats_that_dont_deref(p.hir_id);
348+
self.visit_skipped_ref_pats(p.hir_id);
349349
self.visit_pat_adjustments(p.span, p.hir_id);
350350

351351
self.visit_node_id(p.span, p.hir_id);
@@ -676,10 +676,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
676676
}
677677

678678
#[instrument(skip(self), level = "debug")]
679-
fn visit_ref_pats_that_dont_deref(&mut self, hir_id: hir::HirId) {
680-
if self.fcx.typeck_results.borrow_mut().ref_pats_that_dont_deref_mut().remove(hir_id) {
681-
debug!("node is a ref pat that doesn't deref");
682-
self.typeck_results.ref_pats_that_dont_deref_mut().insert(hir_id);
679+
fn visit_skipped_ref_pats(&mut self, hir_id: hir::HirId) {
680+
if self.fcx.typeck_results.borrow_mut().skipped_ref_pats_mut().remove(hir_id) {
681+
debug!("node is a skipped ref pat");
682+
self.typeck_results.skipped_ref_pats_mut().insert(hir_id);
683683
}
684684
}
685685

compiler/rustc_middle/src/ty/typeck_results.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub struct TypeckResults<'tcx> {
9898

9999
/// Set of reference patterns that match against a match-ergonomics inserted reference
100100
/// (as opposed to against a reference in the scrutinee type).
101-
ref_pats_that_dont_deref: ItemLocalSet,
101+
skipped_ref_pats: ItemLocalSet,
102102

103103
/// Records the reasons that we picked the kind of each closure;
104104
/// not all closures are present in the map.
@@ -232,7 +232,7 @@ impl<'tcx> TypeckResults<'tcx> {
232232
adjustments: Default::default(),
233233
pat_binding_modes: Default::default(),
234234
pat_adjustments: Default::default(),
235-
ref_pats_that_dont_deref: Default::default(),
235+
skipped_ref_pats: Default::default(),
236236
closure_kind_origins: Default::default(),
237237
liberated_fn_sigs: Default::default(),
238238
fru_field_types: Default::default(),
@@ -440,12 +440,12 @@ impl<'tcx> TypeckResults<'tcx> {
440440
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
441441
}
442442

443-
pub fn ref_pats_that_dont_deref(&self) -> LocalSetInContext<'_> {
444-
LocalSetInContext { hir_owner: self.hir_owner, data: &self.ref_pats_that_dont_deref }
443+
pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
444+
LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
445445
}
446446

447-
pub fn ref_pats_that_dont_deref_mut(&mut self) -> LocalSetInContextMut<'_> {
448-
LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.ref_pats_that_dont_deref }
447+
pub fn skipped_ref_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
448+
LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.skipped_ref_pats }
449449
}
450450

451451
/// Does the pattern recursively contain a `ref mut` binding in it?

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,16 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
6565
// we wrap the unadjusted pattern in `PatKind::Deref` repeatedly, consuming the
6666
// adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted
6767
// gets the least-dereferenced type).
68-
let unadjusted = if self.typeck_results.ref_pats_that_dont_deref().contains(pat.hir_id) {
69-
match pat.kind {
70-
hir::PatKind::Ref(inner, _) => self.lower_pattern_unadjusted(inner),
71-
_ => span_bug!(pat.span, "non ref pattern marked as non-deref ref pattern"),
68+
let unadjusted_pat = match pat.kind {
69+
hir::PatKind::Ref(inner, _)
70+
if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) =>
71+
{
72+
self.lower_pattern_unadjusted(inner)
7273
}
73-
} else {
74-
self.lower_pattern_unadjusted(pat)
74+
_ => self.lower_pattern_unadjusted(pat),
7575
};
7676
self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
77-
unadjusted,
77+
unadjusted_pat,
7878
|pat: Box<_>, ref_ty| {
7979
debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
8080
Box::new(Pat {

compiler/rustc_span/src/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,6 @@ symbols! {
380380
alu32,
381381
always,
382382
and,
383-
and_pat_everywhere,
384383
and_then,
385384
anon,
386385
anon_adt,
@@ -1457,6 +1456,7 @@ symbols! {
14571456
receiver,
14581457
recursion_limit,
14591458
reexport_test_harness_main,
1459+
ref_pat_everywhere,
14601460
ref_unwind_safe_trait,
14611461
reference,
14621462
reflect,

tests/ui/match/feature-gate-and_pat_everywhere.stderr renamed to tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/feature-gate-and_pat_everywhere.rs:2:22
2+
--> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
33
|
44
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
55
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) {
1414
| ~
1515

1616
error[E0308]: mismatched types
17-
--> $DIR/feature-gate-and_pat_everywhere.rs:6:17
17+
--> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
1818
|
1919
LL | if let Some(&Some(x)) = &Some(Some(0)) {
2020
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
@@ -25,7 +25,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) {
2525
found reference `&_`
2626

2727
error[E0308]: mismatched types
28-
--> $DIR/feature-gate-and_pat_everywhere.rs:10:22
28+
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
2929
|
3030
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
3131
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -35,7 +35,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
3535
= note: expected type `{integer}`
3636
found mutable reference `&mut _`
3737
note: to declare a mutable binding use: `mut x`
38-
--> $DIR/feature-gate-and_pat_everywhere.rs:10:22
38+
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
3939
|
4040
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
4141
| ^^^^^^

tests/ui/match/and_pat_everywhere-mutability-mismatch.rs renamed to tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![allow(incomplete_features)]
2-
#![feature(and_pat_everywhere)]
2+
#![feature(ref_pat_everywhere)]
33
pub fn main() {
44
if let Some(&x) = Some(0) {
55
//~^ ERROR: mismatched types [E0308]
@@ -9,4 +9,8 @@ pub fn main() {
99
//~^ ERROR: mismatched types [E0308]
1010
let _: u32 = x;
1111
}
12+
if let Some(&x) = &mut Some(0) {
13+
//~^ ERROR: mismatched types [E0308]
14+
let _: u32 = x;
15+
}
1216
}

tests/ui/match/and_pat_everywhere-mutability-mismatch.stderr renamed to tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/and_pat_everywhere-mutability-mismatch.rs:4:17
2+
--> $DIR/ref_pat_everywhere-mutability-mismatch.rs:4:17
33
|
44
LL | if let Some(&x) = Some(0) {
55
| ^^ ------- this expression has type `Option<{integer}>`
@@ -14,7 +14,7 @@ LL | if let Some(x) = Some(0) {
1414
| ~
1515

1616
error[E0308]: mismatched types
17-
--> $DIR/and_pat_everywhere-mutability-mismatch.rs:8:12
17+
--> $DIR/ref_pat_everywhere-mutability-mismatch.rs:8:12
1818
|
1919
LL | if let &Some(x) = &mut Some(0) {
2020
| ^^^^^^^^ ------------ this expression has type `&mut Option<{integer}>`
@@ -24,6 +24,21 @@ LL | if let &Some(x) = &mut Some(0) {
2424
= note: expected mutable reference `&mut Option<{integer}>`
2525
found reference `&_`
2626

27-
error: aborting due to 2 previous errors
27+
error[E0308]: mismatched types
28+
--> $DIR/ref_pat_everywhere-mutability-mismatch.rs:12:17
29+
|
30+
LL | if let Some(&x) = &mut Some(0) {
31+
| ^^ ------------ this expression has type `&mut Option<{integer}>`
32+
| |
33+
| expected integer, found `&_`
34+
|
35+
= note: expected type `{integer}`
36+
found reference `&_`
37+
help: consider removing `&` from the pattern
38+
|
39+
LL | if let Some(x) = &mut Some(0) {
40+
| ~
41+
42+
error: aborting due to 3 previous errors
2843

2944
For more information about this error, try `rustc --explain E0308`.

tests/ui/match/and_pat_everywhere.rs renamed to tests/ui/match/ref_pat_everywhere.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ run-pass
22
#![allow(incomplete_features)]
3-
#![feature(and_pat_everywhere)]
3+
#![feature(ref_pat_everywhere)]
44

55
pub fn main() {
66
if let Some(Some(&x)) = &Some(&Some(0)) {
@@ -12,4 +12,7 @@ pub fn main() {
1212
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
1313
let _: u32 = x;
1414
}
15+
if let Some(Some(&x)) = &Some(&mut Some(0)) {
16+
let _: u32 = x;
17+
}
1518
}

0 commit comments

Comments
 (0)