Address review comments
This commit is contained in:
parent
f37a4d55ee
commit
9d200f2d88
11 changed files with 55 additions and 33 deletions
|
@ -339,8 +339,6 @@ declare_features! (
|
||||||
(incomplete, adt_const_params, "1.56.0", Some(95174)),
|
(incomplete, adt_const_params, "1.56.0", Some(95174)),
|
||||||
/// Allows defining an `#[alloc_error_handler]`.
|
/// Allows defining an `#[alloc_error_handler]`.
|
||||||
(unstable, alloc_error_handler, "1.29.0", Some(51540)),
|
(unstable, alloc_error_handler, "1.29.0", Some(51540)),
|
||||||
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
|
|
||||||
(incomplete, and_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
|
|
||||||
/// Allows trait methods with arbitrary self types.
|
/// Allows trait methods with arbitrary self types.
|
||||||
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
|
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
|
||||||
/// Allows using `const` operands in inline assembly.
|
/// Allows using `const` operands in inline assembly.
|
||||||
|
@ -569,6 +567,8 @@ declare_features! (
|
||||||
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
|
||||||
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
|
||||||
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
||||||
|
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
|
||||||
|
(incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
|
||||||
/// Allows using the `#[register_tool]` attribute.
|
/// Allows using the `#[register_tool]` attribute.
|
||||||
(unstable, register_tool, "1.41.0", Some(66079)),
|
(unstable, register_tool, "1.41.0", Some(66079)),
|
||||||
/// Allows the `#[repr(i128)]` attribute for enums.
|
/// Allows the `#[repr(i128)]` attribute for enums.
|
||||||
|
|
|
@ -2058,7 +2058,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
mutbl: Mutability,
|
mutbl: Mutability,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
pat_info: PatInfo<'tcx, '_>,
|
pat_info: PatInfo<'tcx, '_>,
|
||||||
already_consumed: bool,
|
consumed_inherited_ref: bool,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let expected = self.shallow_resolve(expected);
|
let expected = self.shallow_resolve(expected);
|
||||||
|
@ -2074,13 +2074,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
match *expected.kind() {
|
match *expected.kind() {
|
||||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
|
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
|
||||||
_ => {
|
_ => {
|
||||||
if already_consumed && self.tcx.features().and_pat_everywhere {
|
if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
|
||||||
// We already matched against a match-ergonmics inserted reference,
|
// We already matched against a match-ergonmics inserted reference,
|
||||||
// so we don't need to match against a reference from the original type.
|
// so we don't need to match against a reference from the original type.
|
||||||
// Save this infor for use in lowering later
|
// Save this infor for use in lowering later
|
||||||
self.typeck_results
|
self.typeck_results
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.ref_pats_that_dont_deref_mut()
|
.skipped_ref_pats_mut()
|
||||||
.insert(pat.hir_id);
|
.insert(pat.hir_id);
|
||||||
(expected, expected)
|
(expected, expected)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -345,7 +345,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.visit_ref_pats_that_dont_deref(p.hir_id);
|
self.visit_skipped_ref_pats(p.hir_id);
|
||||||
self.visit_pat_adjustments(p.span, p.hir_id);
|
self.visit_pat_adjustments(p.span, p.hir_id);
|
||||||
|
|
||||||
self.visit_node_id(p.span, p.hir_id);
|
self.visit_node_id(p.span, p.hir_id);
|
||||||
|
@ -676,10 +676,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn visit_ref_pats_that_dont_deref(&mut self, hir_id: hir::HirId) {
|
fn visit_skipped_ref_pats(&mut self, hir_id: hir::HirId) {
|
||||||
if self.fcx.typeck_results.borrow_mut().ref_pats_that_dont_deref_mut().remove(hir_id) {
|
if self.fcx.typeck_results.borrow_mut().skipped_ref_pats_mut().remove(hir_id) {
|
||||||
debug!("node is a ref pat that doesn't deref");
|
debug!("node is a skipped ref pat");
|
||||||
self.typeck_results.ref_pats_that_dont_deref_mut().insert(hir_id);
|
self.typeck_results.skipped_ref_pats_mut().insert(hir_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ pub struct TypeckResults<'tcx> {
|
||||||
|
|
||||||
/// Set of reference patterns that match against a match-ergonomics inserted reference
|
/// Set of reference patterns that match against a match-ergonomics inserted reference
|
||||||
/// (as opposed to against a reference in the scrutinee type).
|
/// (as opposed to against a reference in the scrutinee type).
|
||||||
ref_pats_that_dont_deref: ItemLocalSet,
|
skipped_ref_pats: ItemLocalSet,
|
||||||
|
|
||||||
/// Records the reasons that we picked the kind of each closure;
|
/// Records the reasons that we picked the kind of each closure;
|
||||||
/// not all closures are present in the map.
|
/// not all closures are present in the map.
|
||||||
|
@ -232,7 +232,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
||||||
adjustments: Default::default(),
|
adjustments: Default::default(),
|
||||||
pat_binding_modes: Default::default(),
|
pat_binding_modes: Default::default(),
|
||||||
pat_adjustments: Default::default(),
|
pat_adjustments: Default::default(),
|
||||||
ref_pats_that_dont_deref: Default::default(),
|
skipped_ref_pats: Default::default(),
|
||||||
closure_kind_origins: Default::default(),
|
closure_kind_origins: Default::default(),
|
||||||
liberated_fn_sigs: Default::default(),
|
liberated_fn_sigs: Default::default(),
|
||||||
fru_field_types: Default::default(),
|
fru_field_types: Default::default(),
|
||||||
|
@ -440,12 +440,12 @@ impl<'tcx> TypeckResults<'tcx> {
|
||||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ref_pats_that_dont_deref(&self) -> LocalSetInContext<'_> {
|
pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
|
||||||
LocalSetInContext { hir_owner: self.hir_owner, data: &self.ref_pats_that_dont_deref }
|
LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ref_pats_that_dont_deref_mut(&mut self) -> LocalSetInContextMut<'_> {
|
pub fn skipped_ref_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
|
||||||
LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.ref_pats_that_dont_deref }
|
LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.skipped_ref_pats }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does the pattern recursively contain a `ref mut` binding in it?
|
/// Does the pattern recursively contain a `ref mut` binding in it?
|
||||||
|
|
|
@ -65,16 +65,16 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
// we wrap the unadjusted pattern in `PatKind::Deref` repeatedly, consuming the
|
// we wrap the unadjusted pattern in `PatKind::Deref` repeatedly, consuming the
|
||||||
// adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted
|
// adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted
|
||||||
// gets the least-dereferenced type).
|
// gets the least-dereferenced type).
|
||||||
let unadjusted = if self.typeck_results.ref_pats_that_dont_deref().contains(pat.hir_id) {
|
let unadjusted_pat = match pat.kind {
|
||||||
match pat.kind {
|
hir::PatKind::Ref(inner, _)
|
||||||
hir::PatKind::Ref(inner, _) => self.lower_pattern_unadjusted(inner),
|
if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) =>
|
||||||
_ => span_bug!(pat.span, "non ref pattern marked as non-deref ref pattern"),
|
{
|
||||||
|
self.lower_pattern_unadjusted(inner)
|
||||||
}
|
}
|
||||||
} else {
|
_ => self.lower_pattern_unadjusted(pat),
|
||||||
self.lower_pattern_unadjusted(pat)
|
|
||||||
};
|
};
|
||||||
self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
|
self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
|
||||||
unadjusted,
|
unadjusted_pat,
|
||||||
|pat: Box<_>, ref_ty| {
|
|pat: Box<_>, ref_ty| {
|
||||||
debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
|
debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
|
||||||
Box::new(Pat {
|
Box::new(Pat {
|
||||||
|
|
|
@ -380,7 +380,6 @@ symbols! {
|
||||||
alu32,
|
alu32,
|
||||||
always,
|
always,
|
||||||
and,
|
and,
|
||||||
and_pat_everywhere,
|
|
||||||
and_then,
|
and_then,
|
||||||
anon,
|
anon,
|
||||||
anon_adt,
|
anon_adt,
|
||||||
|
@ -1457,6 +1456,7 @@ symbols! {
|
||||||
receiver,
|
receiver,
|
||||||
recursion_limit,
|
recursion_limit,
|
||||||
reexport_test_harness_main,
|
reexport_test_harness_main,
|
||||||
|
ref_pat_everywhere,
|
||||||
ref_unwind_safe_trait,
|
ref_unwind_safe_trait,
|
||||||
reference,
|
reference,
|
||||||
reflect,
|
reflect,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/feature-gate-and_pat_everywhere.rs:2:22
|
--> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
|
||||||
|
|
|
|
||||||
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
|
@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
||||||
| ~
|
| ~
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/feature-gate-and_pat_everywhere.rs:6:17
|
--> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
|
||||||
|
|
|
|
||||||
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
||||||
|
@ -25,7 +25,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
||||||
found reference `&_`
|
found reference `&_`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/feature-gate-and_pat_everywhere.rs:10:22
|
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
||||||
|
|
|
|
||||||
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
|
| ^^^^^^ ----------------------- 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)) {
|
||||||
= note: expected type `{integer}`
|
= note: expected type `{integer}`
|
||||||
found mutable reference `&mut _`
|
found mutable reference `&mut _`
|
||||||
note: to declare a mutable binding use: `mut x`
|
note: to declare a mutable binding use: `mut x`
|
||||||
--> $DIR/feature-gate-and_pat_everywhere.rs:10:22
|
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
||||||
|
|
|
|
||||||
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
| ^^^^^^
|
| ^^^^^^
|
|
@ -1,5 +1,5 @@
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(and_pat_everywhere)]
|
#![feature(ref_pat_everywhere)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
if let Some(&x) = Some(0) {
|
if let Some(&x) = Some(0) {
|
||||||
//~^ ERROR: mismatched types [E0308]
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
@ -9,4 +9,8 @@ pub fn main() {
|
||||||
//~^ ERROR: mismatched types [E0308]
|
//~^ ERROR: mismatched types [E0308]
|
||||||
let _: u32 = x;
|
let _: u32 = x;
|
||||||
}
|
}
|
||||||
|
if let Some(&x) = &mut Some(0) {
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/and_pat_everywhere-mutability-mismatch.rs:4:17
|
--> $DIR/ref_pat_everywhere-mutability-mismatch.rs:4:17
|
||||||
|
|
|
|
||||||
LL | if let Some(&x) = Some(0) {
|
LL | if let Some(&x) = Some(0) {
|
||||||
| ^^ ------- this expression has type `Option<{integer}>`
|
| ^^ ------- this expression has type `Option<{integer}>`
|
||||||
|
@ -14,7 +14,7 @@ LL | if let Some(x) = Some(0) {
|
||||||
| ~
|
| ~
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/and_pat_everywhere-mutability-mismatch.rs:8:12
|
--> $DIR/ref_pat_everywhere-mutability-mismatch.rs:8:12
|
||||||
|
|
|
|
||||||
LL | if let &Some(x) = &mut Some(0) {
|
LL | if let &Some(x) = &mut Some(0) {
|
||||||
| ^^^^^^^^ ------------ this expression has type `&mut Option<{integer}>`
|
| ^^^^^^^^ ------------ this expression has type `&mut Option<{integer}>`
|
||||||
|
@ -24,6 +24,21 @@ LL | if let &Some(x) = &mut Some(0) {
|
||||||
= note: expected mutable reference `&mut Option<{integer}>`
|
= note: expected mutable reference `&mut Option<{integer}>`
|
||||||
found reference `&_`
|
found reference `&_`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_everywhere-mutability-mismatch.rs:12:17
|
||||||
|
|
|
||||||
|
LL | if let Some(&x) = &mut Some(0) {
|
||||||
|
| ^^ ------------ this expression has type `&mut Option<{integer}>`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&_`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found reference `&_`
|
||||||
|
help: consider removing `&` from the pattern
|
||||||
|
|
|
||||||
|
LL | if let Some(x) = &mut Some(0) {
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,6 +1,6 @@
|
||||||
//@ run-pass
|
//@ run-pass
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(and_pat_everywhere)]
|
#![feature(ref_pat_everywhere)]
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
if let Some(Some(&x)) = &Some(&Some(0)) {
|
||||||
|
@ -12,4 +12,7 @@ pub fn main() {
|
||||||
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
||||||
let _: u32 = x;
|
let _: u32 = x;
|
||||||
}
|
}
|
||||||
|
if let Some(Some(&x)) = &Some(&mut Some(0)) {
|
||||||
|
let _: u32 = x;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue