Skip to content
Draft
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
16 changes: 9 additions & 7 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,10 +648,10 @@ impl Pat {
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
// `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
PatKind::Ref(pat, mutbl) => {
pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
}
// A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }),
Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }),
})?,
// when `P` can be reparsed as a type `T`.
PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
pat.to_ty().map(TyKind::Slice)?
Expand Down Expand Up @@ -696,7 +696,7 @@ impl Pat {
// Trivial wrappers over inner patterns.
PatKind::Box(s)
| PatKind::Deref(s)
| PatKind::Ref(s, _)
| PatKind::Ref(s, _, _)
| PatKind::Paren(s)
| PatKind::Guard(s, _) => s.walk(it),

Expand Down Expand Up @@ -756,7 +756,9 @@ impl Pat {
PatKind::Missing => unreachable!(),
PatKind::Wild => Some("_".to_string()),
PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
PatKind::Ref(pat, pinned, mutbl) => {
pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl)))
}
_ => None,
}
}
Expand Down Expand Up @@ -904,7 +906,7 @@ pub enum PatKind {
Deref(Box<Pat>),

/// A reference pattern (e.g., `&mut (a, b)`).
Ref(Box<Pat>, Mutability),
Ref(Box<Pat>, Pinnedness, Mutability),

/// A literal, const block or path.
Expr(Box<Expr>),
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_ast_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,15 @@ impl Pinnedness {
pub fn is_pinned(self) -> bool {
matches!(self, Self::Pinned)
}

/// Returns `""` (empty string), "mut", `"pin mut "` or `"pin const "` depending
/// on the pinnedness and mutability.
pub fn prefix_str(self, mutbl: Mutability) -> &'static str {
match (self, mutbl) {
(Pinnedness::Pinned, Mutability::Mut) => "pin mut ",
(Pinnedness::Pinned, Mutability::Not) => "pin const ",
(Pinnedness::Not, Mutability::Mut) => "mut ",
(Pinnedness::Not, Mutability::Not) => "",
}
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
PatKind::Deref(inner) => {
break hir::PatKind::Deref(self.lower_pat(inner));
}
PatKind::Ref(inner, mutbl) => {
break hir::PatKind::Ref(self.lower_pat(inner), *mutbl);
PatKind::Ref(inner, pinned, mutbl) => {
break hir::PatKind::Ref(self.lower_pat(inner), *pinned, *mutbl);
}
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
break hir::PatKind::Range(
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1807,8 +1807,14 @@ impl<'a> State<'a> {
self.print_pat(inner);
self.pclose();
}
PatKind::Ref(inner, mutbl) => {
PatKind::Ref(inner, pinned, mutbl) => {
self.word("&");
if pinned.is_pinned() {
self.word("pin ");
if mutbl.is_not() {
self.word("const ");
}
}
if mutbl.is_mut() {
self.word("mut ");
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,11 +867,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
for (binding_span, opt_ref_pat) in finder.ref_pat_for_binding {
if let Some(ref_pat) = opt_ref_pat
&& !finder.cannot_remove.contains(&ref_pat.hir_id)
&& let hir::PatKind::Ref(subpat, mutbl) = ref_pat.kind
&& let hir::PatKind::Ref(subpat, pinned, mutbl) = ref_pat.kind
&& let Some(ref_span) = ref_pat.span.trim_end(subpat.span)
{
let pinned_str = if pinned.is_pinned() { "pinned " } else { "" };
let mutable_str = if mutbl.is_mut() { "mutable " } else { "" };
let msg = format!("consider removing the {mutable_str}borrow");
let msg = format!("consider removing the {pinned_str}{mutable_str}borrow");
suggestions.push((ref_span, msg, "".to_string()));
} else {
let msg = "consider borrowing the pattern binding".to_string();
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,11 +765,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
&& let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value()
&& let node = self.infcx.tcx.hir_node(hir_id)
&& let hir::Node::LetStmt(hir::LetStmt {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
pat: hir::Pat { kind: hir::PatKind::Ref(_, _, _), .. },
..
})
| hir::Node::Param(Param {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
pat: hir::Pat { kind: hir::PatKind::Ref(_, _, _), .. },
..
}) = node
{
Expand Down Expand Up @@ -1444,7 +1444,7 @@ impl<'tcx> Visitor<'tcx> for BindingFinder {
}

fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) -> Self::Result {
if let hir::Pat { kind: hir::PatKind::Ref(_, _), span, .. } = param.pat
if let hir::Pat { kind: hir::PatKind::Ref(_, _, _), span, .. } = param.pat
&& *span == self.span
{
ControlFlow::Break(param.hir_id)
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1697,7 +1697,9 @@ impl<'hir> Pat<'hir> {
match self.kind {
Missing => unreachable!(),
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => {
s.walk_short_(it)
}
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
Slice(before, slice, after) => {
Expand All @@ -1724,7 +1726,7 @@ impl<'hir> Pat<'hir> {
use PatKind::*;
match self.kind {
Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
Slice(before, slice, after) => {
Expand Down Expand Up @@ -1913,7 +1915,7 @@ pub enum PatKind<'hir> {
Deref(&'hir Pat<'hir>),

/// A reference pattern (e.g., `&mut (a, b)`).
Ref(&'hir Pat<'hir>, Mutability),
Ref(&'hir Pat<'hir>, Pinnedness, Mutability),

/// A literal, const block or path.
Expr(&'hir PatExpr<'hir>),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
}
PatKind::Box(ref subpattern)
| PatKind::Deref(ref subpattern)
| PatKind::Ref(ref subpattern, _) => {
| PatKind::Ref(ref subpattern, _, _) => {
try_visit!(visitor.visit_pat(subpattern));
}
PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ fn resolve_local<'tcx>(
is_binding_pat(subpat)
}

PatKind::Ref(_, _)
PatKind::Ref(_, _, _)
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
| PatKind::Missing
| PatKind::Wild
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2020,9 +2020,15 @@ impl<'a> State<'a> {
self.print_pat(inner);
self.pclose();
}
PatKind::Ref(inner, mutbl) => {
PatKind::Ref(inner, pinned, mutbl) => {
let is_range_inner = matches!(inner.kind, PatKind::Range(..));
self.word("&");
if pinned.is_pinned() {
self.word("pin ");
if mutbl.is_not() {
self.word("const ");
}
}
self.word(mutbl.prefix_str());
if is_range_inner {
self.popen();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| hir::PatKind::TupleStruct(_, _, _)
| hir::PatKind::Tuple(_, _)
| hir::PatKind::Box(_)
| hir::PatKind::Ref(_, _)
| hir::PatKind::Ref(_, _, _)
| hir::PatKind::Deref(_)
| hir::PatKind::Expr(_)
| hir::PatKind::Range(_, _, _)
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
debug!("pat_ty(pat={:?}) found adjustment `{:?}`", pat, first_adjust);
return Ok(first_adjust.source);
}
} else if let PatKind::Ref(subpat, _) = pat.kind
} else if let PatKind::Ref(subpat, _, _) = pat.kind
&& self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id)
{
return self.pat_ty_adjusted(subpat);
Expand Down Expand Up @@ -1817,13 +1817,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
self.cat_pattern(place_with_id, subpat, op)?;
}

PatKind::Ref(subpat, _)
PatKind::Ref(subpat, _, _)
if self.cx.typeck_results().skipped_ref_pats().contains(pat.hir_id) =>
{
self.cat_pattern(place_with_id, subpat, op)?;
}

PatKind::Box(subpat) | PatKind::Ref(subpat, _) => {
PatKind::Box(subpat) | PatKind::Ref(subpat, _, _) => {
// box p1, &p1, &mut p1. we can ignore the mutability of
// PatKind::Ref since that information is already contained
// in the type.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2610,7 +2610,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut current_node = parent_node;

while let Node::Pat(parent_pat) = current_node {
if let hir::PatKind::Ref(_, mutability) = parent_pat.kind {
if let hir::PatKind::Ref(_, _, mutability) = parent_pat.kind {
ref_muts.push(mutability);
current_node = self.tcx.parent_hir_node(parent_pat.hir_id);
} else {
Expand Down
Loading
Loading