Skip to content

Commit

Permalink
Auto merge of rust-lang#134248 - oli-obk:patkind-path-removal, r=<try>
Browse files Browse the repository at this point in the history
Merge `PatKind::Path` into `PatKind::Expr`

Follow-up to rust-lang#134228

We always had a duplication where `Path`s could be represented as `PatKind::Path` or `PatKind::Lit(ExprKind::Path)`. We had to handle both everywhere, and still do after rust-lang#134228, so I'm removing it now.
  • Loading branch information
bors committed Jan 23, 2025
2 parents cf577f3 + fd47152 commit 78fe094
Show file tree
Hide file tree
Showing 41 changed files with 203 additions and 322 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
None,
);
// Destructure like a unit struct.
let unit_struct_pat = hir::PatKind::Path(qpath);
let unit_struct_pat = hir::PatKind::Expr(self.arena.alloc(hir::PatExpr {
kind: hir::PatExprKind::Path(qpath),
hir_id: self.next_id(),
span: self.lower_span(lhs.span),
}));
return self.pat_without_dbm(lhs.span, unit_struct_pat);
}
}
Expand Down
33 changes: 23 additions & 10 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
break hir::PatKind::Path(qpath);
let kind = hir::PatExprKind::Path(qpath);
let span = self.lower_span(pattern.span);
let expr = hir::PatExpr { hir_id: pat_hir_id, span, kind };
let expr = self.arena.alloc(expr);
return hir::Pat {
hir_id: self.next_id(),
kind: hir::PatKind::Expr(expr),
span,
default_binding_modes: true,
};
}
PatKind::Struct(qself, path, fields, etc) => {
let qpath = self.lower_qpath(
Expand Down Expand Up @@ -304,16 +313,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}
Some(res) => {
let hir_id = self.next_id();
let res = self.lower_res(res);
hir::PatKind::Path(hir::QPath::Resolved(
None,
self.arena.alloc(hir::Path {
span: self.lower_span(ident.span),
res,
segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
}),
))
let span = self.lower_span(ident.span);
hir::PatKind::Expr(self.arena.alloc(hir::PatExpr {
kind: hir::PatExprKind::Path(hir::QPath::Resolved(
None,
self.arena.alloc(hir::Path {
span,
res,
segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), self.next_id(), res)],
}),
)),
hir_id: self.next_id(),
span,
}))
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,7 @@ impl<'hir> Pat<'hir> {

use PatKind::*;
match self.kind {
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
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)),
Expand All @@ -1418,7 +1418,7 @@ impl<'hir> Pat<'hir> {

use PatKind::*;
match self.kind {
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
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)),
Expand Down Expand Up @@ -1572,9 +1572,6 @@ pub enum PatKind<'hir> {
/// A never pattern `!`.
Never,

/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
Path(QPath<'hir>),

/// A tuple pattern (e.g., `(a, b)`).
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// `0 <= position <= subpats.len()`
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,6 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
try_visit!(visitor.visit_qpath(qpath, pattern.hir_id, pattern.span));
walk_list!(visitor, visit_pat, children);
}
PatKind::Path(ref qpath) => {
try_visit!(visitor.visit_qpath(qpath, pattern.hir_id, pattern.span));
}
PatKind::Struct(ref qpath, fields, _) => {
try_visit!(visitor.visit_qpath(qpath, pattern.hir_id, pattern.span));
walk_list!(visitor, visit_pat_field, fields);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_hir/src/pat_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ impl hir::Pat<'_> {
let mut variants = vec![];
self.walk(|p| match &p.kind {
PatKind::Or(_) => false,
PatKind::Path(hir::QPath::Resolved(_, path))
PatKind::Expr(hir::PatExpr {
kind: hir::PatExprKind::Path(hir::QPath::Resolved(_, path)),
..
})
| PatKind::TupleStruct(hir::QPath::Resolved(_, path), ..)
| PatKind::Struct(hir::QPath::Resolved(_, path), ..) => {
if let Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), id) =
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,6 @@ fn resolve_local<'tcx>(
| PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
| PatKind::Wild
| PatKind::Never
| PatKind::Path(_)
| PatKind::Expr(_)
| PatKind::Range(_, _, _)
| PatKind::Err(_) => false,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
kind: hir::ExprKind::Path(hir::QPath::TypeRelative(qself, _)),
..
})
| hir::Node::Pat(hir::Pat {
kind: hir::PatKind::Path(hir::QPath::TypeRelative(qself, _)),
| hir::Node::PatExpr(hir::PatExpr {
kind: hir::PatExprKind::Path(hir::QPath::TypeRelative(qself, _)),
..
}) if qself.hir_id == self_ty.hir_id => true,
_ => false,
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1905,9 +1905,6 @@ impl<'a> State<'a> {
}
self.pclose();
}
PatKind::Path(ref qpath) => {
self.print_qpath(qpath, true);
}
PatKind::Struct(ref qpath, fields, etc) => {
self.print_qpath(qpath, true);
self.nbsp();
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::PatKind::Binding(_, _, _, _)
| hir::PatKind::Struct(_, _, _)
| hir::PatKind::TupleStruct(_, _, _)
| hir::PatKind::Path(_)
| hir::PatKind::Tuple(_, _)
| hir::PatKind::Box(_)
| hir::PatKind::Ref(_, _)
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ use hir::def::DefKind;
use hir::pat_util::EnumerateAndAdjustIterator as _;
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{HirId, PatKind};
use rustc_hir::{self as hir, HirId, PatExpr, PatExprKind, PatKind};
use rustc_lint::LateContext;
use rustc_middle::hir::place::ProjectionKind;
// Export these here so that Clippy can use them.
Expand Down Expand Up @@ -564,11 +563,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
// FIXME(never_patterns): does this do what I expect?
needs_to_be_read = true;
}
PatKind::Path(qpath) => {
PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => {
// A `Path` pattern is just a name like `Foo`. This is either a
// named constant or else it refers to an ADT variant

let res = self.cx.typeck_results().qpath_res(qpath, pat.hir_id);
let res = self.cx.typeck_results().qpath_res(qpath, *hir_id);
match res {
Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {
// Named constants have to be equated with the value
Expand All @@ -581,7 +580,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
// Otherwise, this is a struct/enum variant, and so it's
// only a read if we need to read the discriminant.
needs_to_be_read |=
self.is_multivariant_adt(place.place.ty(), pat.span);
self.is_multivariant_adt(place.place.ty(), *span);
}
}
}
Expand Down Expand Up @@ -1801,8 +1800,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
}
}

PatKind::Path(_)
| PatKind::Binding(.., None)
PatKind::Binding(.., None)
| PatKind::Expr(..)
| PatKind::Range(..)
| PatKind::Never
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use hir::def_id::LocalDefId;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_data_structures::packed::Pu128;
use rustc_errors::{Applicability, Diag, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, GenericBound, HirId,
Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicateKind, expr_needs_parens,
self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind,
GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind,
WherePredicateKind, expr_needs_parens,
};
use rustc_hir_analysis::collect::suggest_impl_trait;
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
Expand Down Expand Up @@ -1419,8 +1419,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// since the user probably just misunderstood how `let else`
// and `&&` work together.
if let Some((_, hir::Node::LetStmt(local))) = cond_parent
&& let hir::PatKind::Path(qpath) | hir::PatKind::TupleStruct(qpath, _, _) =
&local.pat.kind
&& let hir::PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), .. })
| hir::PatKind::TupleStruct(qpath, _, _) = &local.pat.kind
&& let hir::QPath::Resolved(None, path) = qpath
&& let Some(did) = path
.res
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
| hir::Node::Pat(&hir::Pat {
kind:
hir::PatKind::Path(QPath::TypeRelative(rcvr, segment))
| hir::PatKind::Struct(QPath::TypeRelative(rcvr, segment), ..)
hir::PatKind::Struct(QPath::TypeRelative(rcvr, segment), ..)
| hir::PatKind::TupleStruct(QPath::TypeRelative(rcvr, segment), ..),
span,
..
Expand Down
42 changes: 23 additions & 19 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use rustc_errors::{
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{
self as hir, BindingMode, ByRef, ExprKind, HirId, LangItem, Mutability, Pat, PatKind,
expr_needs_parens,
self as hir, BindingMode, ByRef, ExprKind, HirId, LangItem, Mutability, Pat, PatExpr,
PatExprKind, PatKind, expr_needs_parens,
};
use rustc_infer::infer;
use rustc_middle::traits::PatternOriginExpr;
Expand Down Expand Up @@ -312,9 +312,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'_, 'tcx>) {
let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info;

let path_res = match &pat.kind {
PatKind::Path(qpath) => {
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
let path_res = match pat.kind {
PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref qpath), hir_id, span }) => {
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, *hir_id, *span))
}
_ => None,
};
Expand All @@ -333,6 +333,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
PatKind::Wild | PatKind::Err(_) => expected,
// We allow any type here; we ensure that the type is uninhabited during match checking.
PatKind::Never => expected,
PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref qpath), hir_id, span }) => {
let ty =
self.check_pat_path(*hir_id, *span, qpath, path_res.unwrap(), expected, ti);
self.write_ty(*hir_id, ty);
ty
}
PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
PatKind::Binding(ba, var_id, ident, sub) => {
Expand All @@ -341,9 +347,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
}
PatKind::Path(ref qpath) => {
self.check_pat_path(pat.hir_id, pat.span, qpath, path_res.unwrap(), expected, ti)
}
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
}
Expand Down Expand Up @@ -456,16 +459,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| PatKind::Slice(..) => AdjustMode::Peel,
// A never pattern behaves somewhat like a literal or unit variant.
PatKind::Never => AdjustMode::Peel,
// String and byte-string literals result in types `&str` and `&[u8]` respectively.
// All other literals result in non-reference types.
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
//
// Call `resolve_vars_if_possible` here for inline const blocks.
PatKind::Expr(lt) => match self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)).kind() {
ty::Ref(..) => AdjustMode::Pass,
_ => AdjustMode::Peel,
},
PatKind::Path(_) => match opt_path_res.unwrap() {
PatKind::Expr(PatExpr { kind: PatExprKind::Path(_), .. }) => match opt_path_res.unwrap() {
// These constants can be of a reference type, e.g. `const X: &u8 = &0;`.
// Peeling the reference types too early will cause type checking failures.
// Although it would be possible to *also* peel the types of the constants too.
Expand All @@ -476,6 +470,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// a reference type wherefore peeling doesn't give up any expressiveness.
_ => AdjustMode::Peel,
},

// String and byte-string literals result in types `&str` and `&[u8]` respectively.
// All other literals result in non-reference types.
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
//
// Call `resolve_vars_if_possible` here for inline const blocks.
PatKind::Expr(lt) => match self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)).kind() {
ty::Ref(..) => AdjustMode::Pass,
_ => AdjustMode::Peel,
},

// Ref patterns are complicated, we handle them in `check_pat_ref`.
PatKind::Ref(..) => AdjustMode::Pass,
// A `_` pattern works with any expected type, so there's no need to do anything.
Expand Down Expand Up @@ -1001,7 +1006,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
PatKind::Wild
| PatKind::Never
| PatKind::Binding(..)
| PatKind::Path(..)
| PatKind::Box(..)
| PatKind::Deref(_)
| PatKind::Ref(..)
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use rustc_ast as ast;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::{
BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat, PatKind,
Path, PathSegment, QPath, Ty, TyKind,
BinOp, BinOpKind, Expr, ExprKind, GenericArg, HirId, Impl, Item, ItemKind, Node, Pat, PatExpr,
PatExprKind, PatKind, Path, PathSegment, QPath, Ty, TyKind,
};
use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy};
use rustc_session::{declare_lint_pass, declare_tool_lint};
Expand Down Expand Up @@ -164,11 +164,9 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
TyKind::Path(QPath::Resolved(_, path)) => {
if lint_ty_kind_usage(cx, &path.res) {
let span = match cx.tcx.parent_hir_node(ty.hir_id) {
Node::Pat(Pat {
kind:
PatKind::Path(qpath)
| PatKind::TupleStruct(qpath, ..)
| PatKind::Struct(qpath, ..),
Node::PatExpr(PatExpr { kind: PatExprKind::Path(qpath), .. })
| Node::Pat(Pat {
kind: PatKind::TupleStruct(qpath, ..) | PatKind::Struct(qpath, ..),
..
})
| Node::Expr(
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_lint/src/nonstandard_style.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::FnKind;
use rustc_hir::{AttrArgs, AttrItem, AttrKind, GenericParamKind, PatKind};
use rustc_hir::{AttrArgs, AttrItem, AttrKind, GenericParamKind, PatExprKind, PatKind};
use rustc_middle::ty;
use rustc_session::config::CrateType;
use rustc_session::{declare_lint, declare_lint_pass};
Expand Down Expand Up @@ -527,7 +527,11 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {

fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
// Lint for constants that look like binding identifiers (#7526)
if let PatKind::Path(hir::QPath::Resolved(None, path)) = p.kind {
if let PatKind::Expr(hir::PatExpr {
kind: PatExprKind::Path(hir::QPath::Resolved(None, path)),
..
}) = p.kind
{
if let Res::Def(DefKind::Const, _) = path.res {
if let [segment] = path.segments {
NonUpperCaseGlobals::check_upper_case(
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.unwrap_or_else(PatKind::Error)
}

hir::PatKind::Path(ref qpath) => {
return self.lower_path(qpath, pat.hir_id, pat.span);
}

hir::PatKind::Deref(subpattern) => {
let mutable = self.typeck_results.pat_has_ref_mut_binding(subpattern);
let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
Expand Down
Loading

0 comments on commit 78fe094

Please sign in to comment.