From e40db8a7dd4f9a55ab3ddbe5c88c181b9f3a3316 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 12 Dec 2024 10:37:37 +0000 Subject: [PATCH] Eliminate PatKind::Path --- compiler/rustc_ast_lowering/src/expr.rs | 7 ++- compiler/rustc_ast_lowering/src/pat.rs | 17 ++++-- compiler/rustc_hir/src/hir.rs | 7 +-- compiler/rustc_hir/src/intravisit.rs | 3 -- compiler/rustc_hir/src/pat_util.rs | 5 +- .../rustc_hir_analysis/src/check/region.rs | 1 - .../src/hir_ty_lowering/lint.rs | 4 +- compiler/rustc_hir_pretty/src/lib.rs | 3 -- compiler/rustc_hir_typeck/src/expr.rs | 1 - .../rustc_hir_typeck/src/expr_use_visitor.rs | 10 ++-- .../src/fn_ctxt/suggestions.rs | 10 ++-- .../rustc_hir_typeck/src/method/suggest.rs | 3 +- compiler/rustc_hir_typeck/src/pat.rs | 54 +++++++++++-------- compiler/rustc_lint/src/internal.rs | 10 ++-- compiler/rustc_lint/src/nonstandard_style.rs | 8 ++- .../rustc_mir_build/src/thir/pattern/mod.rs | 4 -- compiler/rustc_passes/src/dead.rs | 7 ++- compiler/rustc_passes/src/input_stats.rs | 1 - src/librustdoc/clean/utils.rs | 3 +- .../clippy_lints/src/equatable_if_let.rs | 2 +- .../clippy_lints/src/manual_let_else.rs | 9 +++- .../src/manual_unwrap_or_default.rs | 4 +- .../src/matches/collapsible_match.rs | 8 ++- .../src/matches/manual_unwrap_or.rs | 8 ++- .../clippy_lints/src/matches/manual_utils.rs | 10 ++-- .../clippy_lints/src/matches/match_as_ref.rs | 4 +- .../src/matches/match_same_arms.rs | 8 ++- .../src/matches/match_wild_enum.rs | 6 +-- .../src/matches/needless_match.rs | 12 ++++- .../src/matches/redundant_pattern_match.rs | 33 +++++++++--- .../clippy_lints/src/matches/single_match.rs | 21 ++++---- .../clippy_lints/src/option_if_let_else.rs | 10 +++- src/tools/clippy/clippy_lints/src/use_self.rs | 4 +- .../clippy/clippy_lints/src/utils/author.rs | 5 -- .../clippy/clippy_utils/src/hir_utils.rs | 2 - src/tools/clippy/clippy_utils/src/lib.rs | 25 +++++++-- tests/ui/thir-print/thir-tree-match.stdout | 52 +++++++++--------- 37 files changed, 228 insertions(+), 153 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a76ca6772e52e..a9b2cd9958961 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1391,7 +1391,12 @@ 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 { + //hir_id: self.lower_node_id(lhs.id), + hir_id: self.next_id(), + span: lhs.span, + kind: hir::PatExprKind::Path(qpath), + })); return self.pat_without_dbm(lhs.span, unit_struct_pat); } } diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index abd314ae74c39..e3f6958eb45d8 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -69,7 +69,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ); - break hir::PatKind::Path(qpath); + let kind = hir::PatExprKind::Path(qpath); + let expr = hir::PatExpr { hir_id: pat_hir_id, span: pattern.span, kind }; + let expr = self.arena.alloc(expr); + return hir::Pat { + hir_id: self.next_id(), + kind: hir::PatKind::Expr(expr), + span: pattern.span, + default_binding_modes: true, + }; } PatKind::Struct(qself, path, fields, etc) => { let qpath = self.lower_qpath( @@ -306,14 +314,17 @@ 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( + let kind = hir::PatExprKind::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 lit = hir::PatExpr { kind, hir_id: self.next_id(), span: ident.span }; + let lit = self.arena.alloc(lit); + hir::PatKind::Expr(lit) } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 951e95a6385d0..3ccfdc65c6240 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1386,7 +1386,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)), @@ -1413,7 +1413,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)), @@ -1566,9 +1566,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` denotes its position. /// `0 <= position <= subpats.len()` diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index ef863aca09052..503ca42cefa03 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -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); diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index bb853985c7d8a..8dd1e4e829274 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -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) = diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index e5f98bdfb7fed..bef8d758b984a 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -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, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index b7d3617fbe739..25e1b1af44c1b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -36,8 +36,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, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 39b6823cf0e0c..7c5f9f03551a2 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -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(); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 3bb518e7f9711..f608ecb5d409d 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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(_, _) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 1f48b703e4ac8..e83b7344f0872 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -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. @@ -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, .. }) => { // 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 @@ -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 diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3756f6339a450..8914efbb4e647 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -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; @@ -1426,8 +1426,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 diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 72a1e4af9bfce..b1352c9dd75db 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -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, .. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 36094657eafd1..cb9f2f00e4dcc 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -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; @@ -250,9 +250,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, }; @@ -271,6 +271,19 @@ 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, + pat.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) => { @@ -279,9 +292,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) } @@ -394,16 +404,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. @@ -414,6 +415,15 @@ 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. @@ -939,7 +949,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::Wild | PatKind::Never | PatKind::Binding(..) - | PatKind::Path(..) | PatKind::Box(..) | PatKind::Deref(_) | PatKind::Ref(..) @@ -1078,6 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_path( &self, hir_id: HirId, + pat_id: HirId, span: Span, qpath: &hir::QPath<'_>, path_resolution: (Res, Option>, &'tcx [hir::PathSegment<'tcx>]), @@ -1135,7 +1145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Err(err) = self.demand_suptype_with_origin(&self.pattern_cause(ti, span), expected, pat_ty) { - self.emit_bad_pat_path(err, hir_id, span, res, pat_res, pat_ty, segments); + self.emit_bad_pat_path(err, pat_id, span, res, pat_res, pat_ty, segments); } pat_ty } @@ -1178,7 +1188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn emit_bad_pat_path( &self, mut e: Diag<'_>, - hir_id: HirId, + pat_id: HirId, pat_span: Span, res: Res, pat_res: Res, @@ -1197,7 +1207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res.descr(), ), ); - match self.tcx.parent_hir_node(hir_id) { + match self.tcx.parent_hir_node(pat_id) { hir::Node::PatField(..) => { e.span_suggestion_verbose( ident.span.shrink_to_hi(), diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index b31a4c74787fa..ec3fba783b5b2 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -6,7 +6,7 @@ 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, + PatExpr, PatExprKind, Path, PathSegment, QPath, Ty, TyKind, }; use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -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( diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index e09049f322fa6..af6149084f056 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -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, PatExpr, PatExprKind, PatKind}; use rustc_middle::ty; use rustc_session::config::CrateType; use rustc_session::{declare_lint, declare_lint_pass}; @@ -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(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( diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 242b62dfa8dde..4ecfdd512cc5d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -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 }; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index c5dc8e68fe847..d519e5653d5eb 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -10,11 +10,10 @@ use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use rustc_abi::FieldIdx; use rustc_data_structures::unord::UnordSet; use rustc_errors::MultiSpan; -use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{Node, PatKind, TyKind}; +use rustc_hir::{self as hir, Node, PatExpr, PatExprKind, PatKind, TyKind}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy::Level; use rustc_middle::query::Providers; @@ -637,8 +636,8 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { let res = self.typeck_results().qpath_res(path, pat.hir_id); self.handle_field_pattern_match(pat, res, fields); } - PatKind::Path(ref qpath) => { - let res = self.typeck_results().qpath_res(qpath, pat.hir_id); + PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, .. }) => { + let res = self.typeck_results().qpath_res(qpath, *hir_id); self.handle_res(res); } PatKind::TupleStruct(ref qpath, fields, dotdot) => { diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 6617cf2f723a9..94c5a00689f4b 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -299,7 +299,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { TupleStruct, Or, Never, - Path, Tuple, Box, Deref, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 99e88f878fba6..8188a9d99fcbc 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -303,7 +303,8 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { return kw::Underscore; } PatKind::Binding(_, _, ident, _) => return ident.name, - PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), + PatKind::TupleStruct(ref p, ..) + | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), PatKind::Or(pats) => { pats.iter().map(|p| name_from_pat(p).to_string()).collect::>().join(" | ") } diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs index 8a5cf7f56d5f6..7ca2c9536998c 100644 --- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs +++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs @@ -56,7 +56,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)), PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a), PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x), - PatKind::Path(_) | PatKind::Expr(_) => true, + PatKind::Expr(_) => true, } } diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs index a70955a7c78da..b3f6adfeffb9a 100644 --- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs @@ -7,7 +7,7 @@ use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{is_lint_allowed, is_never_expr, msrvs, pat_and_expr_can_be_question_mark, peel_blocks}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind}; +use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; @@ -292,7 +292,12 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo // Only do the check if the type is "spelled out" in the pattern if !matches!( pat.kind, - PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) + PatKind::Struct(..) + | PatKind::TupleStruct(..) + | PatKind::Expr(PatExpr { + kind: PatExprKind::Path(..), + .. + }) ) { return; }; diff --git a/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs b/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs index 8f8390b6f3f9e..7b95399c907cb 100644 --- a/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs +++ b/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs @@ -1,6 +1,6 @@ use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, MatchSource, Pat, PatKind, QPath}; +use rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::GenericArgKind; use rustc_session::declare_lint_pass; @@ -68,7 +68,7 @@ fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option { } fn get_none<'tcx>(cx: &LateContext<'tcx>, arm: &Arm<'tcx>) -> Option<&'tcx Expr<'tcx>> { - if let PatKind::Path(QPath::Resolved(_, path)) = arm.pat.kind + if let PatKind::Expr(PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. }) = arm.pat.kind && let Some(def_id) = path.res.opt_def_id() // Since it comes from a pattern binding, we need to get the parent to actually match // against it. diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs index 99a7b8c74be87..da7ef41d7e08d 100644 --- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs @@ -8,7 +8,7 @@ use clippy_utils::{ }; use rustc_errors::MultiSpan; use rustc_hir::LangItem::OptionNone; -use rustc_hir::{Arm, Expr, HirId, Pat, PatKind}; +use rustc_hir::{Arm, Expr, HirId, Pat, PatExpr, PatExprKind, PatKind}; use rustc_lint::LateContext; use rustc_span::Span; @@ -119,7 +119,11 @@ fn arm_is_wild_like(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { } match arm.pat.kind { PatKind::Binding(..) | PatKind::Wild => true, - PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone), + PatKind::Expr(&PatExpr { + kind: PatExprKind::Path(ref qpath), + hir_id, + .. + }) => is_res_lang_ctor(cx, cx.qpath_res(qpath, hir_id), OptionNone), _ => false, } } diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs index 59d3752001178..d98a3b58713cf 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs @@ -7,7 +7,7 @@ use clippy_utils::{is_res_lang_ctor, path_to_local_id, peel_blocks, sugg}; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, ResultErr}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Arm, Expr, Pat, PatKind}; +use rustc_hir::{Arm, Expr, Pat, PatExpr, PatExprKind, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; use rustc_span::sym; @@ -89,7 +89,11 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<(& if arms.len() == 2 && arms.iter().all(|arm| arm.guard.is_none()) && let Some((idx, or_arm)) = arms.iter().enumerate().find(|(_, arm)| match arm.pat.kind { - PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone), + PatKind::Expr(&PatExpr { + kind: PatExprKind::Path(ref qpath), + hir_id, + .. + }) => is_res_lang_ctor(cx, cx.qpath_res(qpath, hir_id), OptionNone), PatKind::TupleStruct(ref qpath, [pat], _) => { matches!(pat.kind, PatKind::Wild) && is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), ResultErr) diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs index bac5cf88cfbf8..59c4af54cc30c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs +++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs @@ -11,7 +11,7 @@ use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_hir::def::Res; -use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath}; +use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatExpr, PatExprKind, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_span::{SyntaxContext, sym}; @@ -256,9 +256,11 @@ pub(super) fn try_parse_pattern<'tcx>( match pat.kind { PatKind::Wild => Some(OptionPat::Wild), PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt), - PatKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionNone) => { - Some(OptionPat::None) - }, + PatKind::Expr(&PatExpr { + kind: PatExprKind::Path(ref qpath), + hir_id, + .. + }) if is_res_lang_ctor(cx, cx.qpath_res(qpath, hir_id), OptionNone) => Some(OptionPat::None), PatKind::TupleStruct(ref qpath, [pattern], _) if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionSome) && pat.span.ctxt() == ctxt => { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs index 6c123649afc2f..9b87e5eff94ea 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks}; use rustc_errors::Applicability; -use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath}; +use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath, PatExpr, PatExprKind}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -59,7 +59,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { matches!( arm.pat.kind, - PatKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionNone) + PatKind::Expr(&PatExpr { kind: PatExprKind::Path(ref qpath), hir_id, .. }) if is_res_lang_ctor(cx, cx.qpath_res(qpath, hir_id), LangItem::OptionNone) ) } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 28e05c273d5c7..89678d556cf12 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -7,7 +7,7 @@ use rustc_arena::DroplessArena; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; -use rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExprKind, PatKind, RangeEnd}; +use rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExprKind, PatKind, PatExpr, RangeEnd}; use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; @@ -292,7 +292,11 @@ impl<'a> NormalizedPat<'a> { Self::Tuple(var_id, pats) }, PatKind::Or(pats) => Self::Or(arena.alloc_from_iter(pats.iter().map(|pat| Self::from_pat(cx, arena, pat)))), - PatKind::Path(ref path) => Self::Path(cx.qpath_res(path, pat.hir_id).opt_def_id()), + PatKind::Expr(&PatExpr { + kind: PatExprKind::Path(ref path), + hir_id, + .. + }) => Self::Path(cx.qpath_res(path, hir_id).opt_def_id()), PatKind::Tuple(pats, wild_idx) => { let field_count = match cx.typeck_results().pat_ty(pat).kind() { ty::Tuple(subs) => subs.len(), diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs index 91e40e4275c07..893a5b630bc7c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs @@ -3,7 +3,7 @@ use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{is_refutable, peel_hir_pat_refs, recurse_or_patterns}; use rustc_errors::Applicability; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::{Arm, Expr, PatKind, PathSegment, QPath, Ty, TyKind}; +use rustc_hir::{Arm, Expr, PatKind, PathSegment, QPath, Ty, TyKind, PatExpr, PatExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, VariantDef}; use rustc_span::sym; @@ -60,8 +60,8 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { // covered by the set of guards that cover it, but that's really hard to do. recurse_or_patterns(arm.pat, |pat| { let path = match &peel_hir_pat_refs(pat).0.kind { - PatKind::Path(path) => { - let id = match cx.qpath_res(path, pat.hir_id) { + PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref path), hir_id, .. }) => { + let id = match cx.qpath_res(path, *hir_id) { Res::Def( DefKind::Const | DefKind::ConstParam | DefKind::AnonConst | DefKind::InlineConst, _, diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs index 0d5575efc2209..9a50938b35f96 100644 --- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs @@ -8,7 +8,9 @@ use clippy_utils::{ }; use rustc_errors::Applicability; use rustc_hir::LangItem::OptionNone; -use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatExprKind, PatKind, Path, QPath}; +use rustc_hir::{ + Arm, BindingMode, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatExprKind, PatKind, PatExpr, Path, QPath, +}; use rustc_lint::LateContext; use rustc_span::sym; @@ -183,7 +185,13 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool { return !matches!(annot, BindingMode(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name; }, // Example: `Custom::TypeA => Custom::TypeB`, or `None => None` - (PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => { + ( + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(QPath::Resolved(_, p_path)), + .. + }), + ExprKind::Path(QPath::Resolved(_, e_path)), + ) => { return over(p_path.segments, e_path.segments, |p_seg, e_seg| { p_seg.ident.name == e_seg.ident.name }); diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index 7e74b36b44158..42153e0a97693 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -9,7 +9,7 @@ use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatExprKind, PatKind, QPath, UnOp}; +use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatExprKind, PatKind, PatExpr, QPath, UnOp}; use rustc_lint::LateContext; use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_span::{Span, Symbol, sym}; @@ -149,7 +149,10 @@ fn find_method_and_type<'tcx>( None } }, - PatKind::Path(ref path) => { + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(ref path), + .. + }) => { if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, check_pat.hir_id) && let Some(variant_id) = cx.tcx.opt_parent(ctor_id) { @@ -349,10 +352,20 @@ fn found_good_method<'tcx>( None } }, - (PatKind::TupleStruct(path_left, patterns, _), PatKind::Path(path_right)) - | (PatKind::Path(path_left), PatKind::TupleStruct(path_right, patterns, _)) - if patterns.len() == 1 => - { + ( + PatKind::TupleStruct(path_left, patterns, _), + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(path_right), + .. + }), + ) + | ( + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(path_left), + .. + }), + PatKind::TupleStruct(path_right, patterns, _), + ) if patterns.len() == 1 => { if let PatKind::Wild = patterns[0].kind { find_good_method_for_match( cx, @@ -387,7 +400,13 @@ fn found_good_method<'tcx>( None } }, - (PatKind::Path(path_left), PatKind::Wild) => get_good_method(cx, arms, path_left), + ( + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(path_left), + .. + }), + PatKind::Wild, + ) => get_good_method(cx, arms, path_left), _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs index b1d0686ffc42e..0c12dd91457e7 100644 --- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs @@ -114,7 +114,7 @@ fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, exp } let (pat, pat_ref_count) = peel_hir_pat_refs(arm.pat); - let (msg, sugg) = if let PatKind::Path(_) | PatKind::Expr(_) = pat.kind + let (msg, sugg) = if let PatKind::Expr(_) = pat.kind && let (ty, ty_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(ex)) && let Some(spe_trait_id) = cx.tcx.lang_items().structural_peq_trait() && let Some(pe_trait_id) = cx.tcx.lang_items().eq_trait() @@ -331,14 +331,16 @@ impl<'a> PatState<'a> { #[expect(clippy::similar_names)] fn add_pat<'tcx>(&mut self, cx: &'a PatCtxt<'tcx>, pat: &'tcx Pat<'_>) -> bool { match pat.kind { - PatKind::Path(_) - if match *cx.typeck.pat_ty(pat).peel_refs().kind() { - ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()), - ty::Tuple(tys) => !tys.is_empty(), - ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1), - ty::Slice(..) => true, - _ => false, - } => + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(_), + .. + }) if match *cx.typeck.pat_ty(pat).peel_refs().kind() { + ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()), + ty::Tuple(tys) => !tys.is_empty(), + ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1), + ty::Slice(..) => true, + _ => false, + } => { matches!(self, Self::Wild) }, @@ -386,7 +388,6 @@ impl<'a> PatState<'a> { | PatKind::Binding(_, _, _, None) | PatKind::Expr(_) | PatKind::Range(..) - | PatKind::Path(_) | PatKind::Never | PatKind::Err(_) => { *self = PatState::Wild; diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs index 6d9e75f51d66e..624be86cc1b0d 100644 --- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs +++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs @@ -7,7 +7,9 @@ use clippy_utils::{ use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::def::Res; -use rustc_hir::{Arm, BindingMode, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp}; +use rustc_hir::{ + Arm, BindingMode, Expr, ExprKind, MatchSource, Mutability, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, UnOp, +}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::SyntaxContext; @@ -281,7 +283,11 @@ fn try_convert_match<'tcx>( fn is_none_or_err_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { match arm.pat.kind { - PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone), + PatKind::Expr(&PatExpr { + kind: PatExprKind::Path(ref qpath), + hir_id, + .. + }) => is_res_lang_ctor(cx, cx.qpath_res(qpath, hir_id), OptionNone), PatKind::TupleStruct(ref qpath, [first_pat], _) => { is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), ResultErr) && matches!(first_pat.kind, PatKind::Wild) diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 05c5be0300282..18ac2be2cfb2c 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -10,7 +10,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{Visitor, walk_inf, walk_ty}; use rustc_hir::{ self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl, - ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, + ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind, }; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; @@ -257,7 +257,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last() // get the path from the pattern - && let PatKind::Path(QPath::Resolved(_, path)) + && let PatKind::Expr(&PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. }) | PatKind::TupleStruct(QPath::Resolved(_, path), _, _) | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind && cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity() diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 4dcc8ac7fb0af..6bad78cf87185 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -708,11 +708,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { self.qpath(qpath); self.slice(fields, |pat| self.pat(pat)); }, - PatKind::Path(ref qpath) => { - bind!(self, qpath); - kind!("Path(ref {qpath})"); - self.qpath(qpath); - }, PatKind::Tuple(fields, skip_pos) => { bind!(self, fields); kind!("Tuple({fields}, {skip_pos:?})"); diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index d1d0abd469093..c24611a304dfa 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -524,7 +524,6 @@ impl HirEqInterExpr<'_, '_, '_> { } eq }, - (PatKind::Path(l), PatKind::Path(r)) => self.eq_qpath(l, r), (&PatKind::Expr(l), &PatKind::Expr(r)) => self.eq_pat_expr(l, r), (&PatKind::Tuple(l, ls), &PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)), (&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => { @@ -1120,7 +1119,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_pat(pat); } }, - PatKind::Path(ref qpath) => self.hash_qpath(qpath), PatKind::Range(s, e, i) => { if let Some(s) = s { self.hash_pat_expr(s); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d42e40acbc081..930d440b7ac52 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -106,8 +106,8 @@ use rustc_hir::{ self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat, - PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, - TyKind, UnOp, def, + PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, + TraitItemRef, TraitRef, TyKind, UnOp, def, }; use rustc_lexer::{TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -561,7 +561,20 @@ macro_rules! maybe_path { }; } maybe_path!(Expr, ExprKind); -maybe_path!(Pat, PatKind); +impl<'hir> MaybePath<'hir> for Pat<'hir> { + fn hir_id(&self) -> HirId { + self.hir_id + } + fn qpath_opt(&self) -> Option<&QPath<'hir>> { + match &self.kind { + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(qpath), + .. + }) => Some(qpath), + _ => None, + } + } +} maybe_path!(Ty, TyKind); /// If `maybe_path` is a path node, resolves it, otherwise returns `Res::Err` @@ -1754,7 +1767,11 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)), PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), - PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id), + PatKind::Expr(PatExpr { + kind: PatExprKind::Path(qpath), + hir_id, + .. + }) => is_enum_variant(cx, qpath, *hir_id), PatKind::Or(pats) => { // TODO: should be the honest check, that pats is exhaustive set are_refutable(cx, pats) diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 916f296ccfc6b..910582ae4d9e9 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -26,16 +26,16 @@ params: [ body: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0) kind: Scope { - region_scope: Node(26) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26)) + region_scope: Node(28) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).28)) value: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0) kind: Block { @@ -47,7 +47,7 @@ body: expr: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0) kind: Scope { @@ -56,14 +56,14 @@ body: value: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0) kind: Match { scrutinee: Expr { ty: Foo - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0) kind: Scope { @@ -72,7 +72,7 @@ body: value: Expr { ty: Foo - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0) kind: VarRef { @@ -123,16 +123,16 @@ body: body: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(13)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(14)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) kind: Scope { - region_scope: Node(14) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14)) + region_scope: Node(15) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).15)) value: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(13)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(14)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) kind: Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) }, neg: false) @@ -140,8 +140,8 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).13)) - scope: Node(13) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14)) + scope: Node(14) span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0) } Arm { @@ -175,16 +175,16 @@ body: body: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(19)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(20)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) kind: Scope { - region_scope: Node(20) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20)) + region_scope: Node(21) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).21)) value: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(19)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(20)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) kind: Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) }, neg: false) @@ -192,8 +192,8 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).19)) - scope: Node(19) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20)) + scope: Node(20) span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0) } Arm { @@ -219,16 +219,16 @@ body: body: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) kind: Scope { - region_scope: Node(25) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).25)) + region_scope: Node(27) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).27)) value: Expr { ty: bool - temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None } + temp_lifetime: TempLifetime { temp_lifetime: Some(Node(26)), backwards_incompatible: None } span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) kind: Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) }, neg: false) @@ -236,8 +236,8 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).24)) - scope: Node(24) + lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26)) + scope: Node(26) span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0) } ]