Remove ref_pat_everywhere
This commit is contained in:
parent
b21b74b5e6
commit
a32fb2f8aa
8 changed files with 14 additions and 191 deletions
|
@ -181,6 +181,7 @@ declare_features! (
|
||||||
(removed, pushpop_unsafe, "1.2.0", None, None),
|
(removed, pushpop_unsafe, "1.2.0", None, None),
|
||||||
(removed, quad_precision_float, "1.0.0", None, None),
|
(removed, quad_precision_float, "1.0.0", None, None),
|
||||||
(removed, quote, "1.33.0", Some(29601), None),
|
(removed, quote, "1.33.0", Some(29601), None),
|
||||||
|
(removed, ref_pat_everywhere, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024")),
|
||||||
(removed, reflect, "1.0.0", Some(27749), None),
|
(removed, reflect, "1.0.0", Some(27749), None),
|
||||||
/// Allows using the `#[register_attr]` attribute.
|
/// Allows using the `#[register_attr]` attribute.
|
||||||
(removed, register_attr, "1.65.0", Some(66080),
|
(removed, register_attr, "1.65.0", Some(66080),
|
||||||
|
|
|
@ -571,8 +571,6 @@ declare_features! (
|
||||||
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
(unstable, raw_ref_op, "1.41.0", Some(64490)),
|
||||||
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
|
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
|
||||||
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
|
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
|
||||||
/// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
|
|
||||||
(incomplete, ref_pat_everywhere, "1.79.0", 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.
|
||||||
|
|
|
@ -2125,25 +2125,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
mut expected: Ty<'tcx>,
|
mut expected: Ty<'tcx>,
|
||||||
mut pat_info: PatInfo<'tcx, '_>,
|
mut pat_info: PatInfo<'tcx, '_>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
// FIXME: repace with `bool` once final decision on 1 vs 2 layers is made
|
let new_match_ergonomics =
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024;
|
||||||
enum MatchErgonomicsMode {
|
|
||||||
EatOneLayer,
|
|
||||||
EatTwoLayers,
|
|
||||||
Legacy,
|
|
||||||
}
|
|
||||||
|
|
||||||
let match_ergonomics_mode =
|
if new_match_ergonomics {
|
||||||
if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
|
|
||||||
MatchErgonomicsMode::EatOneLayer
|
|
||||||
} else if self.tcx.features().ref_pat_everywhere {
|
|
||||||
MatchErgonomicsMode::EatTwoLayers
|
|
||||||
} else {
|
|
||||||
MatchErgonomicsMode::Legacy
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut inherited_ref_mutbl_match = false;
|
|
||||||
if match_ergonomics_mode != MatchErgonomicsMode::Legacy {
|
|
||||||
if pat_mutbl == Mutability::Not {
|
if pat_mutbl == Mutability::Not {
|
||||||
// Prevent the inner pattern from binding with `ref mut`.
|
// Prevent the inner pattern from binding with `ref mut`.
|
||||||
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(
|
pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(
|
||||||
|
@ -2151,20 +2136,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
|
if let ByRef::Yes(inh_mut) = pat_info.binding_mode
|
||||||
inherited_ref_mutbl_match = pat_mutbl <= inh_mut;
|
&& pat_mutbl <= inh_mut
|
||||||
}
|
|
||||||
|
|
||||||
if inherited_ref_mutbl_match {
|
|
||||||
pat_info.binding_mode = ByRef::No;
|
|
||||||
if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer {
|
|
||||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
|
||||||
self.check_pat(inner, expected, pat_info);
|
|
||||||
return expected;
|
|
||||||
}
|
|
||||||
} else if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer
|
|
||||||
&& pat_mutbl == Mutability::Mut
|
|
||||||
{
|
{
|
||||||
|
pat_info.binding_mode = ByRef::No;
|
||||||
|
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
||||||
|
self.check_pat(inner, expected, pat_info);
|
||||||
|
return expected;
|
||||||
|
} else if pat_mutbl == Mutability::Mut {
|
||||||
// `&mut` patterns pell off `&` references
|
// `&mut` patterns pell off `&` references
|
||||||
let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references(
|
let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references(
|
||||||
pat,
|
pat,
|
||||||
|
@ -2204,33 +2183,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// the bad interactions of the given hack detailed in (note_1).
|
// the bad interactions of the given hack detailed in (note_1).
|
||||||
debug!("check_pat_ref: expected={:?}", expected);
|
debug!("check_pat_ref: expected={:?}", expected);
|
||||||
match *expected.kind() {
|
match *expected.kind() {
|
||||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => {
|
ty::Ref(_, r_ty, r_mutbl) if r_mutbl >= pat_mutbl && new_match_ergonomics => {
|
||||||
if r_mutbl == Mutability::Not
|
if r_mutbl == Mutability::Not {
|
||||||
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy
|
|
||||||
{
|
|
||||||
pat_info.max_ref_mutbl = MutblCap::Not;
|
pat_info.max_ref_mutbl = MutblCap::Not;
|
||||||
}
|
}
|
||||||
|
|
||||||
(expected, r_ty)
|
(expected, r_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// `&` pattern eats `&mut` reference
|
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => (expected, r_ty),
|
||||||
ty::Ref(_, r_ty, Mutability::Mut)
|
|
||||||
if pat_mutbl == Mutability::Not
|
|
||||||
&& match_ergonomics_mode != MatchErgonomicsMode::Legacy =>
|
|
||||||
{
|
|
||||||
(expected, r_ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ if inherited_ref_mutbl_match
|
|
||||||
&& match_ergonomics_mode == MatchErgonomicsMode::EatTwoLayers =>
|
|
||||||
{
|
|
||||||
// We already matched against a match-ergonmics inserted reference,
|
|
||||||
// so we don't need to match against a reference from the original type.
|
|
||||||
// Save this info for use in lowering later
|
|
||||||
self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
|
|
||||||
(expected, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let inner_ty = self.next_ty_var(inner.span);
|
let inner_ty = self.next_ty_var(inner.span);
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
pub fn main() {
|
|
||||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
|
||||||
//~^ ERROR: mismatched types [E0308]
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(&Some(x)) = &Some(Some(0)) {
|
|
||||||
//~^ ERROR: mismatched types [E0308]
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
|
||||||
//~^ ERROR: mismatched types [E0308]
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
|
|
||||||
|
|
|
||||||
LL | if let Some(Some(&x)) = &Some(&Some(0)) {
|
|
||||||
| ^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
|
||||||
| |
|
|
||||||
| expected integer, found `&_`
|
|
||||||
|
|
|
||||||
= note: expected type `{integer}`
|
|
||||||
found reference `&_`
|
|
||||||
help: consider removing `&` from the pattern
|
|
||||||
|
|
|
||||||
LL | if let Some(Some(x)) = &Some(&Some(0)) {
|
|
||||||
| ~
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
|
|
||||||
|
|
|
||||||
LL | if let Some(&Some(x)) = &Some(Some(0)) {
|
|
||||||
| ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>`
|
|
||||||
| |
|
|
||||||
| expected `Option<{integer}>`, found `&_`
|
|
||||||
|
|
|
||||||
= note: expected enum `Option<{integer}>`
|
|
||||||
found reference `&_`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
|
||||||
|
|
|
||||||
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
|
||||||
| ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
|
|
||||||
| |
|
|
||||||
| expected integer, found `&mut _`
|
|
||||||
|
|
|
||||||
= note: expected type `{integer}`
|
|
||||||
found mutable reference `&mut _`
|
|
||||||
note: to declare a mutable binding use: `mut x`
|
|
||||||
--> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
|
|
||||||
|
|
|
||||||
LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
|
||||||
| ^^^^^^
|
|
||||||
help: consider removing `&mut` from the pattern
|
|
||||||
|
|
|
||||||
LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) {
|
|
||||||
| ~
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
|
@ -1,12 +0,0 @@
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(ref_pat_everywhere)]
|
|
||||||
pub fn main() {
|
|
||||||
if let Some(&x) = Some(0) {
|
|
||||||
//~^ ERROR: mismatched types [E0308]
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(&mut x) = Some(&0) {
|
|
||||||
//~^ ERROR: mismatched types [E0308]
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/ref_pat_everywhere-fail.rs:4:17
|
|
||||||
|
|
|
||||||
LL | if let Some(&x) = Some(0) {
|
|
||||||
| ^^ ------- this expression has type `Option<{integer}>`
|
|
||||||
| |
|
|
||||||
| expected integer, found `&_`
|
|
||||||
|
|
|
||||||
= note: expected type `{integer}`
|
|
||||||
found reference `&_`
|
|
||||||
help: consider removing `&` from the pattern
|
|
||||||
|
|
|
||||||
LL | if let Some(x) = Some(0) {
|
|
||||||
| ~
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
|
||||||
|
|
|
||||||
LL | if let Some(&mut x) = Some(&0) {
|
|
||||||
| ^^^^^^ -------- this expression has type `Option<&{integer}>`
|
|
||||||
| |
|
|
||||||
| types differ in mutability
|
|
||||||
|
|
|
||||||
= note: expected reference `&{integer}`
|
|
||||||
found mutable reference `&mut _`
|
|
||||||
note: to declare a mutable binding use: `mut x`
|
|
||||||
--> $DIR/ref_pat_everywhere-fail.rs:8:17
|
|
||||||
|
|
|
||||||
LL | if let Some(&mut x) = Some(&0) {
|
|
||||||
| ^^^^^^
|
|
||||||
help: consider removing `&mut` from the pattern
|
|
||||||
|
|
|
||||||
LL | if let Some(x) = Some(&0) {
|
|
||||||
| ~
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
|
@ -1,24 +0,0 @@
|
||||||
//@ run-pass
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![feature(ref_pat_everywhere)]
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
if let Some(Some(&x)) = &Some(&Some(0)) {
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(&Some(x)) = &Some(Some(0)) {
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(Some(&x)) = &Some(&mut Some(0)) {
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let &Some(x) = &mut Some(0) {
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
if let Some(&x) = &mut Some(0) {
|
|
||||||
let _: u32 = x;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue