Require DerefMut if deref pattern has nested ref mut binding
This commit is contained in:
parent
b56279569b
commit
5fdc7555c1
@ -2017,6 +2017,30 @@ fn check_pat_deref(
|
|||||||
let ty = self.normalize(span, ty);
|
let ty = self.normalize(span, ty);
|
||||||
let ty = self.try_structurally_resolve_type(span, ty);
|
let ty = self.try_structurally_resolve_type(span, ty);
|
||||||
self.check_pat(inner, ty, pat_info);
|
self.check_pat(inner, ty, pat_info);
|
||||||
|
|
||||||
|
// Check if the pattern has any `ref mut` bindings, which would require
|
||||||
|
// `DerefMut` to be emitted in MIR building instead of just `Deref`.
|
||||||
|
let mut needs_mut = false;
|
||||||
|
inner.walk(|pat| {
|
||||||
|
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
|
||||||
|
&& let Some(ty::BindByReference(ty::Mutability::Mut)) =
|
||||||
|
self.typeck_results.borrow().pat_binding_modes().get(id)
|
||||||
|
{
|
||||||
|
needs_mut = true;
|
||||||
|
// No need to continue recursing
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if needs_mut {
|
||||||
|
self.register_bound(
|
||||||
|
expected,
|
||||||
|
tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
|
||||||
|
self.misc(span),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
expected
|
expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
tests/ui/pattern/deref-patterns/ref-mut.rs
Normal file
17
tests/ui/pattern/deref-patterns/ref-mut.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#![feature(deref_patterns)]
|
||||||
|
//~^ WARN the feature `deref_patterns` is incomplete
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match &mut vec![1] {
|
||||||
|
deref!(x) => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &mut Rc::new(1) {
|
||||||
|
deref!(x) => {}
|
||||||
|
//~^ ERROR the trait bound `Rc<{integer}>: DerefMut` is not satisfied
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
20
tests/ui/pattern/deref-patterns/ref-mut.stderr
Normal file
20
tests/ui/pattern/deref-patterns/ref-mut.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
warning: the feature `deref_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/ref-mut.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(deref_patterns)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #87121 <https://github.com/rust-lang/rust/issues/87121> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Rc<{integer}>: DerefMut` is not satisfied
|
||||||
|
--> $DIR/ref-mut.rs:13:9
|
||||||
|
|
|
||||||
|
LL | deref!(x) => {}
|
||||||
|
| ^^^^^^^^^ the trait `DerefMut` is not implemented for `Rc<{integer}>`
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `deref` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user