mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 20:28:33 +00:00
Support let &mut x = &&mut 0;
This commit is contained in:
parent
4cd87c463c
commit
b6c409723b
@ -299,18 +299,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if mutbls_match {
|
if mutbls_match {
|
||||||
(expected, INITIAL_BM, true)
|
(expected, INITIAL_BM, true)
|
||||||
} else {
|
} else {
|
||||||
let mut new_bm = def_bm;
|
let (new_ty, new_bm) = if mutbl == Mutability::Mut {
|
||||||
if new_bm.0 == ByRef::Yes(Mutability::Mut) && mutbl == Mutability::Not {
|
self.peel_off_references(pat, expected, def_bm, Mutability::Not)
|
||||||
new_bm.0 = ByRef::Yes(Mutability::Not);
|
} else {
|
||||||
}
|
let new_byref = if def_bm.0 == ByRef::Yes(Mutability::Mut) {
|
||||||
(expected, new_bm, false)
|
ByRef::Yes(Mutability::Not)
|
||||||
|
} else {
|
||||||
|
def_bm.0
|
||||||
|
};
|
||||||
|
(expected, BindingAnnotation(new_byref, def_bm.1))
|
||||||
|
};
|
||||||
|
(new_ty, new_bm, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(expected, INITIAL_BM, mutbls_match)
|
(expected, INITIAL_BM, mutbls_match)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AdjustMode::Peel => {
|
AdjustMode::Peel => {
|
||||||
let peeled = self.peel_off_references(pat, expected, def_bm);
|
let peeled = self.peel_off_references(pat, expected, def_bm, Mutability::Mut);
|
||||||
(peeled.0, peeled.1, false)
|
(peeled.0, peeled.1, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,6 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
pat: &'tcx Pat<'tcx>,
|
pat: &'tcx Pat<'tcx>,
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
mut def_bm: BindingAnnotation,
|
mut def_bm: BindingAnnotation,
|
||||||
|
max_mutability: Mutability,
|
||||||
) -> (Ty<'tcx>, BindingAnnotation) {
|
) -> (Ty<'tcx>, BindingAnnotation) {
|
||||||
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||||
@ -403,7 +410,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
//
|
//
|
||||||
// See the examples in `ui/match-defbm*.rs`.
|
// See the examples in `ui/match-defbm*.rs`.
|
||||||
let mut pat_adjustments = vec![];
|
let mut pat_adjustments = vec![];
|
||||||
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
|
while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
|
||||||
|
&& inner_mutability <= max_mutability
|
||||||
|
{
|
||||||
debug!("inspecting {:?}", expected);
|
debug!("inspecting {:?}", expected);
|
||||||
|
|
||||||
debug!("current discriminant is Ref, inserting implicit deref");
|
debug!("current discriminant is Ref, inserting implicit deref");
|
||||||
|
@ -38,4 +38,13 @@ pub fn main() {
|
|||||||
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
|
||||||
let _: &u32 = x;
|
let _: &u32 = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let &mut x = &&mut 0;
|
||||||
|
let _: &u32 = x;
|
||||||
|
|
||||||
|
let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
|
||||||
|
let _: &u32 = x;
|
||||||
|
|
||||||
|
let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0;
|
||||||
|
let _: &u32 = x;
|
||||||
}
|
}
|
||||||
|
@ -17,4 +17,12 @@ pub fn main() {
|
|||||||
if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
|
if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: mismatched types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let &mut x = &&0;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: &u32 = x;
|
||||||
|
|
||||||
|
let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
let _: &u32 = x;
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@ error[E0308]: mismatched types
|
|||||||
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
|
LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) {
|
||||||
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
| ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>`
|
||||||
| |
|
| |
|
||||||
| types differ in mutability
|
| expected `Option<{integer}>`, found `&mut _`
|
||||||
|
|
|
|
||||||
= note: expected reference `&Option<{integer}>`
|
= note: expected enum `Option<{integer}>`
|
||||||
found mutable reference `&mut _`
|
found mutable reference `&mut _`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
@ -46,6 +46,30 @@ help: consider removing `&` from the pattern
|
|||||||
LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) {
|
LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) {
|
||||||
| ~
|
| ~
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:9
|
||||||
|
|
|
||||||
|
LL | let &mut x = &&0;
|
||||||
|
| ^^^^^^ --- this expression has type `&&{integer}`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
| help: to declare a mutable variable use: `mut x`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:9
|
||||||
|
|
|
||||||
|
LL | let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
|
||||||
|
| ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
|
||||||
|
| |
|
||||||
|
| expected integer, found `&mut _`
|
||||||
|
| help: to declare a mutable variable use: `mut x`
|
||||||
|
|
|
||||||
|
= note: expected type `{integer}`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
Loading…
Reference in New Issue
Block a user