Skip to content

Commit 5fdc755

Browse files
Require DerefMut if deref pattern has nested ref mut binding
1 parent b562795 commit 5fdc755

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+24
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20172017
let ty = self.normalize(span, ty);
20182018
let ty = self.try_structurally_resolve_type(span, ty);
20192019
self.check_pat(inner, ty, pat_info);
2020+
2021+
// Check if the pattern has any `ref mut` bindings, which would require
2022+
// `DerefMut` to be emitted in MIR building instead of just `Deref`.
2023+
let mut needs_mut = false;
2024+
inner.walk(|pat| {
2025+
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
2026+
&& let Some(ty::BindByReference(ty::Mutability::Mut)) =
2027+
self.typeck_results.borrow().pat_binding_modes().get(id)
2028+
{
2029+
needs_mut = true;
2030+
// No need to continue recursing
2031+
false
2032+
} else {
2033+
true
2034+
}
2035+
});
2036+
if needs_mut {
2037+
self.register_bound(
2038+
expected,
2039+
tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
2040+
self.misc(span),
2041+
);
2042+
}
2043+
20202044
expected
20212045
}
20222046

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(deref_patterns)]
2+
//~^ WARN the feature `deref_patterns` is incomplete
3+
4+
use std::rc::Rc;
5+
6+
fn main() {
7+
match &mut vec![1] {
8+
deref!(x) => {}
9+
_ => {}
10+
}
11+
12+
match &mut Rc::new(1) {
13+
deref!(x) => {}
14+
//~^ ERROR the trait bound `Rc<{integer}>: DerefMut` is not satisfied
15+
_ => {}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
warning: the feature `deref_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/ref-mut.rs:1:12
3+
|
4+
LL | #![feature(deref_patterns)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #87121 <https://github.com/rust-lang/rust/issues/87121> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0277]: the trait bound `Rc<{integer}>: DerefMut` is not satisfied
11+
--> $DIR/ref-mut.rs:13:9
12+
|
13+
LL | deref!(x) => {}
14+
| ^^^^^^^^^ the trait `DerefMut` is not implemented for `Rc<{integer}>`
15+
|
16+
= note: this error originates in the macro `deref` (in Nightly builds, run with -Z macro-backtrace for more info)
17+
18+
error: aborting due to 1 previous error; 1 warning emitted
19+
20+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)