Skip to content

Commit 0e64ced

Browse files
authored
Rollup merge of #150121 - Zalathar:pin-pat, r=Nadrieril
mir_build: Don't use a mixture of THIR pattern kinds for pin-patterns While looking for improvements to match-lowering, I had been trying to figure out why pin-patterns sometimes use `PatKind::Deref` and sometimes use `PatKind::DerefPattern`, which seemed confusing to me. In particular, both pattern kinds are being used with an inner type of `&` or `&mut`, which is very surprising. The conclusion I came to was that `DerefPattern` (normally associated with calls to Deref/DerefMut) was only being used for *implicit* pin-patterns produced by match-ergonomics adjustment, whereas `Deref` was being used for explicit pin-patterns. The inconsistency seems like a mistake to me, so this PR removes all uses of `DerefPattern` for pin-patterns, and consistently uses `PatKind::Deref` for pin-patterns instead. I'm not entirely happy with that outcome, because I think pin-patterns should probably have their own `thir::PatKind` variant, but this change will at least make that easier to achieve in a later PR. r? Nadrieril
2 parents 0f0d850 + 1ae9604 commit 0e64ced

File tree

6 files changed

+35
-40
lines changed

6 files changed

+35
-40
lines changed

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_middle::hir::place::ProjectionKind;
2121
// Export these here so that Clippy can use them.
2222
pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection};
2323
use rustc_middle::mir::FakeReadCause;
24+
use rustc_middle::thir::DerefPatBorrowMode;
2425
use rustc_middle::ty::{
2526
self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment,
2627
};
@@ -890,7 +891,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
890891
// Deref patterns on boxes don't borrow, so we ignore them here.
891892
// HACK: this could be a fake pattern corresponding to a deref inserted by match
892893
// ergonomics, in which case `pat.hir_id` will be the id of the subpattern.
893-
if let hir::ByRef::Yes(_, mutability) =
894+
if let DerefPatBorrowMode::Borrow(mutability) =
894895
self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(), subpattern)
895896
{
896897
let bk = ty::BorrowKind::from_mutbl(mutability);
@@ -1837,9 +1838,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
18371838
) -> Result<PlaceWithHirId<'tcx>, Cx::Error> {
18381839
match self.cx.typeck_results().deref_pat_borrow_mode(base_place.place.ty(), inner) {
18391840
// Deref patterns on boxes are lowered using a built-in deref.
1840-
hir::ByRef::No => self.cat_deref(hir_id, base_place),
1841+
DerefPatBorrowMode::Box => self.cat_deref(hir_id, base_place),
18411842
// For other types, we create a temporary to match on.
1842-
hir::ByRef::Yes(_, mutability) => {
1843+
DerefPatBorrowMode::Borrow(mutability) => {
18431844
let re_erased = self.cx.tcx().lifetimes.re_erased;
18441845
let ty = Ty::new_ref(self.cx.tcx(), re_erased, target_ty, mutability);
18451846
// A deref pattern stores the result of `Deref::deref` or `DerefMut::deref_mut` ...

compiler/rustc_middle/src/thir.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::ops::Index;
1414
use std::sync::Arc;
1515

1616
use rustc_abi::{FieldIdx, Integer, Size, VariantIdx};
17-
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
17+
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece, Mutability};
1818
use rustc_hir as hir;
1919
use rustc_hir::def_id::DefId;
2020
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
@@ -811,11 +811,11 @@ pub enum PatKind<'tcx> {
811811
DerefPattern {
812812
subpattern: Box<Pat<'tcx>>,
813813
/// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or
814-
/// `DerefMut::deref_mut`, and if so, which. This is `ByRef::No` for deref patterns on
814+
/// `DerefMut::deref_mut`, and if so, which. This is `DerefPatBorrowMode::Box` for deref patterns on
815815
/// boxes; they are lowered using a built-in deref rather than a method call, thus they
816816
/// don't borrow the scrutinee.
817817
#[type_visitable(ignore)]
818-
borrow: ByRef,
818+
borrow: DerefPatBorrowMode,
819819
},
820820

821821
/// One of the following:
@@ -879,6 +879,12 @@ pub enum PatKind<'tcx> {
879879
Error(ErrorGuaranteed),
880880
}
881881

882+
#[derive(Copy, Clone, Debug, HashStable)]
883+
pub enum DerefPatBorrowMode {
884+
Borrow(Mutability),
885+
Box,
886+
}
887+
882888
/// A range pattern.
883889
/// The boundaries must be of the same type and that type must be numeric.
884890
#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]

compiler/rustc_middle/src/ty/typeck_results.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
1111
use rustc_hir::hir_id::OwnerId;
1212
use rustc_hir::{
1313
self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
14-
Pinnedness,
1514
};
1615
use rustc_index::IndexVec;
1716
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -21,6 +20,7 @@ use rustc_span::Span;
2120
use crate::hir::place::Place as HirPlace;
2221
use crate::infer::canonical::Canonical;
2322
use crate::mir::FakeReadCause;
23+
use crate::thir::DerefPatBorrowMode;
2424
use crate::traits::ObligationCause;
2525
use crate::ty::{
2626
self, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, GenericArgKind, GenericArgs,
@@ -491,13 +491,18 @@ impl<'tcx> TypeckResults<'tcx> {
491491
/// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner
492492
/// pattern's scrutinee by calling `DerefMut::deref_mut`, and otherwise we call `Deref::deref`.
493493
/// However, for boxes we can use a built-in deref instead, which doesn't borrow the scrutinee;
494-
/// in this case, we return `ByRef::No`.
495-
pub fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: &hir::Pat<'_>) -> ByRef {
494+
/// in this case, we return `DerefPatBorrowMode::Box`.
495+
pub fn deref_pat_borrow_mode(
496+
&self,
497+
pointer_ty: Ty<'_>,
498+
inner: &hir::Pat<'_>,
499+
) -> DerefPatBorrowMode {
496500
if pointer_ty.is_box() {
497-
ByRef::No
501+
DerefPatBorrowMode::Box
498502
} else {
499-
let mutable = self.pat_has_ref_mut_binding(inner);
500-
ByRef::Yes(Pinnedness::Not, if mutable { Mutability::Mut } else { Mutability::Not })
503+
let mutability =
504+
if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
505+
DerefPatBorrowMode::Borrow(mutability)
501506
}
502507
}
503508

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use std::sync::Arc;
22

33
use rustc_abi::FieldIdx;
4-
use rustc_hir::ByRef;
54
use rustc_middle::mir::*;
65
use rustc_middle::thir::*;
7-
use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt};
6+
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
87

98
use crate::builder::Builder;
109
use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder};
@@ -287,8 +286,9 @@ impl<'tcx> MatchPairTree<'tcx> {
287286
None
288287
}
289288

289+
// FIXME: Pin-patterns should probably have their own pattern kind,
290+
// instead of overloading `PatKind::Deref` via the pattern type.
290291
PatKind::Deref { ref subpattern }
291-
| PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) }
292292
if let Some(ref_ty) = pattern.ty.pinned_ty()
293293
&& ref_ty.is_ref() =>
294294
{
@@ -302,12 +302,8 @@ impl<'tcx> MatchPairTree<'tcx> {
302302
None
303303
}
304304

305-
PatKind::DerefPattern { borrow: ByRef::Yes(Pinnedness::Pinned, _), .. } => {
306-
rustc_middle::bug!("RefPin pattern on non-`Pin` type {:?}", pattern.ty)
307-
}
308-
309305
PatKind::Deref { ref subpattern }
310-
| PatKind::DerefPattern { ref subpattern, borrow: ByRef::No } => {
306+
| PatKind::DerefPattern { ref subpattern, borrow: DerefPatBorrowMode::Box } => {
311307
MatchPairTree::for_pattern(
312308
place_builder.deref(),
313309
subpattern,
@@ -320,7 +316,7 @@ impl<'tcx> MatchPairTree<'tcx> {
320316

321317
PatKind::DerefPattern {
322318
ref subpattern,
323-
borrow: ByRef::Yes(Pinnedness::Not, mutability),
319+
borrow: DerefPatBorrowMode::Borrow(mutability),
324320
} => {
325321
// Create a new temporary for each deref pattern.
326322
// FIXME(deref_patterns): dedup temporaries to avoid multiple `deref()` calls?

compiler/rustc_mir_build/src/builder/matches/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use std::mem;
1111
use std::sync::Arc;
1212

1313
use itertools::{Itertools, Position};
14-
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
14+
use rustc_abi::{FIRST_VARIANT, VariantIdx};
1515
use rustc_data_structures::fx::FxIndexMap;
1616
use rustc_data_structures::stack::ensure_sufficient_stack;
17-
use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node, Pinnedness};
17+
use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node};
1818
use rustc_middle::middle::region::{self, TempLifetime};
1919
use rustc_middle::mir::*;
2020
use rustc_middle::thir::{self, *};
@@ -920,10 +920,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
920920
visit_subpat(self, subpattern, &user_tys.deref(), f);
921921
}
922922

923-
PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } => {
924-
visit_subpat(self, subpattern, &user_tys.leaf(FieldIdx::ZERO).deref(), f);
925-
}
926-
927923
PatKind::DerefPattern { ref subpattern, .. } => {
928924
visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f);
929925
}

compiler/rustc_mir_build/src/thir/pattern/mod.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use rustc_abi::{FieldIdx, Integer};
1111
use rustc_errors::codes::*;
1212
use rustc_hir::def::{CtorOf, DefKind, Res};
1313
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
14-
use rustc_hir::{self as hir, ByRef, LangItem, Mutability, Pinnedness, RangeEnd};
14+
use rustc_hir::{self as hir, LangItem, RangeEnd};
1515
use rustc_index::Idx;
1616
use rustc_infer::infer::TyCtxtInferExt;
1717
use rustc_middle::mir::interpret::LitToConstInput;
1818
use rustc_middle::thir::{
19-
Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
19+
Ascription, DerefPatBorrowMode, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
2020
};
2121
use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment};
2222
use rustc_middle::ty::layout::IntegerExt;
@@ -114,16 +114,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
114114
let borrow = self.typeck_results.deref_pat_borrow_mode(adjust.source, pat);
115115
PatKind::DerefPattern { subpattern: thir_pat, borrow }
116116
}
117-
PatAdjust::PinDeref => {
118-
let mutable = self.typeck_results.pat_has_ref_mut_binding(pat);
119-
PatKind::DerefPattern {
120-
subpattern: thir_pat,
121-
borrow: ByRef::Yes(
122-
Pinnedness::Pinned,
123-
if mutable { Mutability::Mut } else { Mutability::Not },
124-
),
125-
}
126-
}
117+
PatAdjust::PinDeref => PatKind::Deref { subpattern: thir_pat },
127118
};
128119
Box::new(Pat { span, ty: adjust.source, kind })
129120
});
@@ -334,7 +325,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
334325
}
335326
hir::PatKind::Box(subpattern) => PatKind::DerefPattern {
336327
subpattern: self.lower_pattern(subpattern),
337-
borrow: hir::ByRef::No,
328+
borrow: DerefPatBorrowMode::Box,
338329
},
339330

340331
hir::PatKind::Slice(prefix, slice, suffix) => {

0 commit comments

Comments
 (0)