Skip to content

Commit ec9d26a

Browse files
Require DerefMut if deref pattern has nested ref mut binding
1 parent 32b0a42 commit ec9d26a

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
@@ -2000,6 +2000,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20002000
let ty = self.normalize(span, ty);
20012001
let ty = self.try_structurally_resolve_type(span, ty);
20022002
self.check_pat(inner, ty, pat_info);
2003+
2004+
// Check if the pattern has any `ref mut` bindings, which would require
2005+
// `DerefMut` to be emitted in MIR building instead of just `Deref`.
2006+
let mut needs_mut = false;
2007+
inner.walk(|pat| {
2008+
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
2009+
&& let Some(ty::BindByReference(ty::Mutability::Mut)) =
2010+
self.typeck_results.borrow().pat_binding_modes().get(id)
2011+
{
2012+
needs_mut = true;
2013+
// No need to continue recursing
2014+
false
2015+
} else {
2016+
true
2017+
}
2018+
});
2019+
if needs_mut {
2020+
self.register_bound(
2021+
expected,
2022+
tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
2023+
self.misc(span),
2024+
);
2025+
}
2026+
20032027
expected
20042028
}
20052029

+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)