diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index fe8ccca072bfb..403d28df7bf27 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1384,7 +1384,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::Lit(self.arena.alloc(hir::PatLit { + hir_id: self.lower_node_id(lhs.id), + span: lhs.span, + kind: hir::PatLitKind::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 25702e3c835cf..8750897da49a4 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -70,7 +70,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, ); - break hir::PatKind::Path(qpath); + let kind = hir::PatLitKind::Path(qpath); + let lit = hir::PatLit { hir_id: pat_hir_id, span: pattern.span, kind }; + let lit = self.arena.alloc(lit); + return hir::Pat { + hir_id: self.next_id(), + kind: hir::PatKind::Lit(lit), + span: pattern.span, + default_binding_modes: true, + }; } PatKind::Struct(qself, path, fields, etc) => { let qpath = self.lower_qpath( @@ -299,14 +307,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::PatLitKind::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::PatLit { kind, hir_id: self.next_id(), span: ident.span }; + let lit = self.arena.alloc(lit); + hir::PatKind::Lit(lit) } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 10fc150017842..d9ccb64d5ead1 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1137,7 +1137,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { - Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true, + Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Err(_) => true, Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(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)), @@ -1164,7 +1164,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { - Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {} + Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Err(_) => {} Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(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)), @@ -1317,9 +1317,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 7a0b1a069b2a8..ddee06b3ab63d 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -669,9 +669,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 2ebbb4a06b6bf..51ee8f142ac23 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -106,7 +106,10 @@ impl hir::Pat<'_> { let mut variants = vec![]; self.walk(|p| match &p.kind { PatKind::Or(_) => false, - PatKind::Path(hir::QPath::Resolved(_, path)) + PatKind::Lit(hir::PatLit { + kind: hir::PatLitKind::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 b9cb48cafdcd2..2b295c362a1bd 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -700,7 +700,6 @@ fn resolve_local<'tcx>( | PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..) | PatKind::Wild | PatKind::Never - | PatKind::Path(_) | PatKind::Lit(_) | 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 fd49e7e44398b..5df91a4f91abf 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -37,7 +37,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .. }) | hir::Node::Pat(hir::Pat { - kind: hir::PatKind::Path(hir::QPath::TypeRelative(qself, _)), + kind: + hir::PatKind::Lit(hir::PatLit { + kind: hir::PatLitKind::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 075391d0bcaa4..c05889af5b1e1 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1771,9 +1771,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 9e4e285580b4b..8088e7331cf4e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -468,7 +468,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 27ec2e9e0d482..877f4a101598c 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, PatKind, PatLit, PatLitKind}; use rustc_lint::LateContext; use rustc_middle::hir::place::ProjectionKind; // Export these here so that Clippy can use them. @@ -560,11 +559,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::Lit(PatLit { kind: PatLitKind::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 @@ -1793,8 +1792,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } } - PatKind::Path(_) - | PatKind::Binding(.., None) + PatKind::Binding(.., None) | PatKind::Lit(..) | 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 ddcd90a2a9da6..0670cfab4c6ac 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, + self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, + GenericBound, HirId, Node, PatLit, PatLitKind, Path, QPath, Stmt, StmtKind, TyKind, + WherePredicateKind, }; use rustc_hir_analysis::collect::suggest_impl_trait; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; @@ -1427,8 +1427,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::Lit(PatLit { kind: PatLitKind::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 0148aebaf9b27..5c3eaab8b2f35 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -178,8 +178,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 e56c2658bdfab..b9794343bebea 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -10,7 +10,9 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind}; +use rustc_hir::{ + self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind, PatLit, PatLitKind, +}; use rustc_infer::infer; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; @@ -225,9 +227,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::Lit(&PatLit { kind: PatLitKind::Path(ref qpath), hir_id, span }) => { + Some(self.resolve_ty_and_res_fully_qualified_call(qpath, hir_id, span)) } _ => None, }; @@ -246,6 +248,11 @@ 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::Lit(&PatLit { kind: PatLitKind::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::Lit(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) => { @@ -254,9 +261,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) } @@ -364,16 +368,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::Lit(lt) => match self.resolve_vars_if_possible(self.check_pat_lit_unadjusted(lt)).kind() { - ty::Ref(..) => AdjustMode::Pass, - _ => AdjustMode::Peel, - }, - PatKind::Path(_) => match opt_path_res.unwrap() { + PatKind::Lit(PatLit { kind: PatLitKind::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. @@ -384,6 +379,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::Lit(lt) => match self.resolve_vars_if_possible(self.check_pat_lit_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. @@ -905,7 +909,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::Wild | PatKind::Never | PatKind::Binding(..) - | PatKind::Path(..) | PatKind::Box(..) | PatKind::Deref(_) | PatKind::Ref(..) diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 482650e04e85c..5e5b106a30aff 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, + PatLit, PatLitKind, Path, PathSegment, QPath, Ty, TyKind, }; use rustc_middle::ty::{self, GenericArgsRef, Ty as MiddleTy}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -167,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { let span = match cx.tcx.parent_hir_node(ty.hir_id) { Node::Pat(Pat { kind: - PatKind::Path(qpath) + PatKind::Lit(PatLit { kind: PatLitKind::Path(qpath), .. }) | PatKind::TupleStruct(qpath, ..) | PatKind::Struct(qpath, ..), .. diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 4d8ebf2909ef8..e4d1a359276d4 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::{GenericParamKind, PatKind}; +use rustc_hir::{GenericParamKind, PatKind, PatLit, PatLitKind}; use rustc_middle::ty; use rustc_session::config::CrateType; use rustc_session::{declare_lint, declare_lint_pass}; @@ -528,7 +528,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::Lit(PatLit { + kind: PatLitKind::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 e01827125e375..fa2618e1fc322 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -318,10 +318,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 ecf8d34ad8405..dc0d03637d54b 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, PatKind, PatLit, PatLitKind, 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::Lit(PatLit { kind: PatLitKind::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 f2a37307ceeb8..9833fec637772 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -295,7 +295,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 d59b4e4081ca4..b0413aa57b657 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::Lit(PatLit { kind: PatLitKind::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_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 541753f145623..05f370bcd42f3 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -510,7 +510,6 @@ impl HirEqInterExpr<'_, '_, '_> { } eq }, - (PatKind::Path(l), PatKind::Path(r)) => self.eq_qpath(l, r), (&PatKind::Lit(l), &PatKind::Lit(r)) => self.eq_pat_lit(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)) => { @@ -1100,7 +1099,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_lit(s); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 8d48cdd3cbb4f..3784178176c0b 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -107,7 +107,7 @@ use rustc_hir::{ 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, + TyKind, UnOp, def, PatLit, PatLitKind, }; use rustc_lexer::{TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; @@ -550,7 +550,17 @@ 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::Lit(PatLit { kind: PatLitKind::Path(qpath), .. }) => Some(qpath), + _ => None, + } + } +} maybe_path!(Ty, TyKind); /// If `maybe_path` is a path node, resolves it, otherwise returns `Res::Err` @@ -1743,7 +1753,7 @@ 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::Lit(PatLit { kind: PatLitKind::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/associated-consts/associated-const-match-patterns.stderr b/tests/ui/associated-consts/associated-const-match-patterns.stderr new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr index 6a2bb3ec09adf..22ca511fbfd91 100644 --- a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr +++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr @@ -6,8 +6,8 @@ LL | Trait::CONST => {} | help: you can add the `dyn` keyword if you want a trait object | -LL | ::CONST => {} - | ++++ + +LL | dyn Trait::CONST => {} + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/pattern/issue-110508.stderr b/tests/ui/pattern/issue-110508.stderr new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/constref.stderr b/tests/ui/rfcs/rfc-2005-default-binding-mode/constref.stderr new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/ui/suggestions/const-in-struct-pat.stderr b/tests/ui/suggestions/const-in-struct-pat.stderr index d4056e09cc364..e2447e2d1fd45 100644 --- a/tests/ui/suggestions/const-in-struct-pat.stderr +++ b/tests/ui/suggestions/const-in-struct-pat.stderr @@ -9,11 +9,7 @@ LL | let Thing { foo } = t; | | | expected `String`, found `foo` | `foo` is interpreted as a unit struct, not a new binding - | -help: bind the struct field to a different name instead - | -LL | let Thing { foo: other_foo } = t; - | +++++++++++ + | help: introduce a new binding instead: `other_foo` error: aborting due to 1 previous error 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) } ]