Skip to content

Commit 935c282

Browse files
Extract helper, fix comment on DerefPure
1 parent 81f3341 commit 935c282

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,20 +2003,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20032003

20042004
// Check if the pattern has any `ref mut` bindings, which would require
20052005
// `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 {
2006+
// We do this *after* checking the inner pattern, since we want to make
2007+
// sure to apply any match-ergonomics adjustments.
2008+
if self.typeck_results.borrow().pat_has_ref_mut_binding(inner) {
20202009
self.register_bound(
20212010
expected,
20222011
tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),

compiler/rustc_middle/src/ty/typeck_results.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,31 @@ impl<'tcx> TypeckResults<'tcx> {
430430
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
431431
}
432432

433+
/// Does the pattern recursively contain a `ref mut` binding in it?
434+
///
435+
/// This is used to determined whether a `deref` pattern should emit a `Deref`
436+
/// or `DerefMut` call for its pattern scrutinee.
437+
///
438+
/// This is computed from the typeck results since we want to make
439+
/// sure to apply any match-ergonomics adjustments, which we cannot
440+
/// determine from the HIR alone.
441+
pub fn pat_has_ref_mut_binding(&self, pat: &'tcx hir::Pat<'tcx>) -> bool {
442+
let mut has_ref_mut = false;
443+
pat.walk(|pat| {
444+
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
445+
&& let Some(ty::BindByReference(ty::Mutability::Mut)) =
446+
self.pat_binding_modes().get(id)
447+
{
448+
has_ref_mut = true;
449+
// No need to continue recursing
450+
false
451+
} else {
452+
true
453+
}
454+
});
455+
has_ref_mut
456+
}
457+
433458
/// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
434459
/// by the closure.
435460
pub fn closure_min_captures_flattened(

library/core/src/ops/deref.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ impl<T: ?Sized> DerefMut for &mut T {
275275
}
276276
}
277277

278-
/// UwU
278+
/// FIXME(deref_patterns): Figure out the invariants implementations need to uphold.
279279
#[unstable(feature = "deref_pure_trait", issue = "87121")]
280280
#[cfg_attr(not(bootstrap), lang = "deref_pure")]
281281
pub unsafe trait DerefPure {}

0 commit comments

Comments
 (0)