Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fc1d7d2

Browse files
Extract helper, fix comment on DerefPure
1 parent 5fdc755 commit fc1d7d2

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

‎compiler/rustc_hir_typeck/src/pat.rs‎

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

20212021
// Check if the pattern has any `ref mut` bindings, which would require
20222022
// `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 {
2023+
// We do this *after* checking the inner pattern, since we want to make
2024+
// sure to apply any match-ergonomics adjustments.
2025+
if self.typeck_results.borrow().pat_has_ref_mut_binding(inner) {
20372026
self.register_bound(
20382027
expected,
20392028
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: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,15 @@ impl<T: ?Sized> DerefMut for &mut T {
275275
}
276276
}
277277

278-
/// UwU
278+
/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
279+
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
280+
/// of deref patterns.
281+
///
282+
/// FIXME(deref_patterns): The precise semantics are undecided; the rough idea is that
283+
/// successive calls to `deref`/`deref_mut` without intermediate mutation should be
284+
/// idempotent, in the sense that they return the same value as far as pattern-matching
285+
/// is concerned. Calls to `deref`/`deref_mut`` must leave the pointer itself likewise
286+
/// unchanged.
279287
#[unstable(feature = "deref_pure_trait", issue = "87121")]
280288
#[cfg_attr(not(bootstrap), lang = "deref_pure")]
281289
pub unsafe trait DerefPure {}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /