Extract helper, fix comment on DerefPure
This commit is contained in:
parent
5fdc7555c1
commit
fc1d7d275b
@ -2020,20 +2020,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Check if the pattern has any `ref mut` bindings, which would require
|
// Check if the pattern has any `ref mut` bindings, which would require
|
||||||
// `DerefMut` to be emitted in MIR building instead of just `Deref`.
|
// `DerefMut` to be emitted in MIR building instead of just `Deref`.
|
||||||
let mut needs_mut = false;
|
// We do this *after* checking the inner pattern, since we want to make
|
||||||
inner.walk(|pat| {
|
// sure to apply any match-ergonomics adjustments.
|
||||||
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
|
if self.typeck_results.borrow().pat_has_ref_mut_binding(inner) {
|
||||||
&& 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(
|
self.register_bound(
|
||||||
expected,
|
expected,
|
||||||
tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
|
tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)),
|
||||||
|
@ -430,6 +430,31 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Does the pattern recursively contain a `ref mut` binding in it?
|
||||||
|
///
|
||||||
|
/// This is used to determined whether a `deref` pattern should emit a `Deref`
|
||||||
|
/// or `DerefMut` call for its pattern scrutinee.
|
||||||
|
///
|
||||||
|
/// This is computed from the typeck results since we want to make
|
||||||
|
/// sure to apply any match-ergonomics adjustments, which we cannot
|
||||||
|
/// determine from the HIR alone.
|
||||||
|
pub fn pat_has_ref_mut_binding(&self, pat: &'tcx hir::Pat<'tcx>) -> bool {
|
||||||
|
let mut has_ref_mut = false;
|
||||||
|
pat.walk(|pat| {
|
||||||
|
if let hir::PatKind::Binding(_, id, _, _) = pat.kind
|
||||||
|
&& let Some(ty::BindByReference(ty::Mutability::Mut)) =
|
||||||
|
self.pat_binding_modes().get(id)
|
||||||
|
{
|
||||||
|
has_ref_mut = true;
|
||||||
|
// No need to continue recursing
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
has_ref_mut
|
||||||
|
}
|
||||||
|
|
||||||
/// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
|
/// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured
|
||||||
/// by the closure.
|
/// by the closure.
|
||||||
pub fn closure_min_captures_flattened(
|
pub fn closure_min_captures_flattened(
|
||||||
|
@ -275,7 +275,15 @@ impl<T: ?Sized> DerefMut for &mut T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UwU
|
/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
|
||||||
|
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
|
||||||
|
/// of deref patterns.
|
||||||
|
///
|
||||||
|
/// FIXME(deref_patterns): The precise semantics are undecided; the rough idea is that
|
||||||
|
/// successive calls to `deref`/`deref_mut` without intermediate mutation should be
|
||||||
|
/// idempotent, in the sense that they return the same value as far as pattern-matching
|
||||||
|
/// is concerned. Calls to `deref`/`deref_mut`` must leave the pointer itself likewise
|
||||||
|
/// unchanged.
|
||||||
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
||||||
#[cfg_attr(not(bootstrap), lang = "deref_pure")]
|
#[cfg_attr(not(bootstrap), lang = "deref_pure")]
|
||||||
pub unsafe trait DerefPure {}
|
pub unsafe trait DerefPure {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user