Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up TypeckResults::extract_binding_mode #137712

Merged
merged 1 commit into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,12 @@ pub enum PatKind<'hir> {
/// The `HirId` is the canonical ID for the variable being bound,
/// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
/// which is the pattern ID of the first `x`.
///
/// The `BindingMode` is what's provided by the user, before match
/// ergonomics are applied. For the binding mode actually in use,
/// see [`TypeckResults::extract_binding_mode`].
///
/// [`TypeckResults::extract_binding_mode`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.extract_binding_mode
Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),

/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
Expand Down
68 changes: 32 additions & 36 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,48 +895,44 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
match pat.kind {
PatKind::Binding(_, canonical_id, ..) => {
debug!("walk_pat: binding place={:?} pat={:?}", place, pat);
if let Some(bm) = self
let bm = self
.cx
.typeck_results()
.extract_binding_mode(tcx.sess, pat.hir_id, pat.span)
{
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
.extract_binding_mode(tcx.sess, pat.hir_id, pat.span);
debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);

// pat_ty: the type of the binding being produced.
let pat_ty = self.node_ty(pat.hir_id)?;
debug!("walk_pat: pat_ty={:?}", pat_ty);
// pat_ty: the type of the binding being produced.
let pat_ty = self.node_ty(pat.hir_id)?;
debug!("walk_pat: pat_ty={:?}", pat_ty);

let def = Res::Local(canonical_id);
if let Ok(ref binding_place) =
self.cat_res(pat.hir_id, pat.span, pat_ty, def)
{
self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id);
}
let def = Res::Local(canonical_id);
if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) {
self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id);
}

// Subtle: MIR desugaring introduces immutable borrows for each pattern
// binding when lowering pattern guards to ensure that the guard does not
// modify the scrutinee.
if has_guard {
self.delegate.borrow_mut().borrow(
place,
discr_place.hir_id,
BorrowKind::Immutable,
);
}
// Subtle: MIR desugaring introduces immutable borrows for each pattern
// binding when lowering pattern guards to ensure that the guard does not
// modify the scrutinee.
if has_guard {
self.delegate.borrow_mut().borrow(
place,
discr_place.hir_id,
BorrowKind::Immutable,
);
}

// It is also a borrow or copy/move of the value being matched.
// In a cases of pattern like `let pat = upvar`, don't use the span
// of the pattern, as this just looks confusing, instead use the span
// of the discriminant.
match bm.0 {
hir::ByRef::Yes(m) => {
let bk = ty::BorrowKind::from_mutbl(m);
self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
}
hir::ByRef::No => {
debug!("walk_pat binding consuming pat");
self.consume_or_copy(place, discr_place.hir_id);
}
// It is also a borrow or copy/move of the value being matched.
// In a cases of pattern like `let pat = upvar`, don't use the span
// of the pattern, as this just looks confusing, instead use the span
// of the discriminant.
match bm.0 {
hir::ByRef::Yes(m) => {
let bk = ty::BorrowKind::from_mutbl(m);
self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
}
hir::ByRef::No => {
debug!("walk_pat binding consuming pat");
self.consume_or_copy(place, discr_place.hir_id);
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
match p.kind {
hir::PatKind::Binding(..) => {
let typeck_results = self.fcx.typeck_results.borrow();
if let Some(bm) =
typeck_results.extract_binding_mode(self.tcx().sess, p.hir_id, p.span)
{
self.typeck_results.pat_binding_modes_mut().insert(p.hir_id, bm);
}
let bm = typeck_results.extract_binding_mode(self.tcx().sess, p.hir_id, p.span);
self.typeck_results.pat_binding_modes_mut().insert(p.hir_id, bm);
}
hir::PatKind::Struct(_, fields, _) => {
for field in fields {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,10 @@ impl<'tcx> TypeckResults<'tcx> {
matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _))))
}

pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
self.pat_binding_modes().get(id).copied().or_else(|| {
/// Returns the computed binding mode for a `PatKind::Binding` pattern
/// (after match ergonomics adjustments).
pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> BindingMode {
self.pat_binding_modes().get(id).copied().unwrap_or_else(|| {
s.dcx().span_bug(sp, "missing binding mode");
})
}
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,6 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
pat.each_binding_or_first(&mut |_, id, span, _| match cx
.typeck_results()
.extract_binding_mode(cx.sess(), id, span)
.unwrap()
.0
{
ByRef::No if !is_copy(cx, cx.typeck_results().node_type(id)) => {
Expand Down
Loading