diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 082d5e88ac754..0adf4f898ab6d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -869,11 +869,11 @@ pub enum PatKind { Struct(Option>, Path, ThinVec, PatFieldsRest), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - TupleStruct(Option>, Path, ThinVec>), + TupleStruct(Option>, Path, ThinVec), /// An or-pattern `A | B | C`. /// Invariant: `pats.len() >= 2`. - Or(ThinVec>), + Or(ThinVec), /// A possibly qualified path pattern. /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants @@ -882,7 +882,7 @@ pub enum PatKind { Path(Option>, Path), /// A tuple pattern (`(a, b)`). - Tuple(ThinVec>), + Tuple(ThinVec), /// A `box` pattern. Box(Box), @@ -900,7 +900,7 @@ pub enum PatKind { Range(Option>, Option>, Spanned), /// A slice pattern `[a, b, c]`. - Slice(ThinVec>), + Slice(ThinVec), /// A rest pattern `..`. /// @@ -2579,7 +2579,7 @@ pub enum TyPatKind { /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`). Range(Option>, Option>, Spanned), - Or(ThinVec>), + Or(ThinVec), /// Placeholder for a pattern that wasn't syntactically well formed in some way. Err(ErrorGuaranteed), diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 68b3d2b036865..ebd5aa6e93d83 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -389,9 +389,9 @@ macro_rules! common_visitor_and_walkers { ThinVec<(NodeId, Path)>, ThinVec, ThinVec, - ThinVec>, + ThinVec, ThinVec>, - ThinVec>, + ThinVec, ); // This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable` diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index ed159f37051c1..03aeb064d7f11 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -154,7 +154,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_pat_tuple( &mut self, - pats: &[Box], + pats: &[Pat], ctx: &str, ) -> (&'hir [hir::Pat<'hir>], hir::DotDotPos) { let mut elems = Vec::with_capacity(pats.len()); @@ -209,7 +209,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// When encountering `($binding_mode $ident @)? ..` (`slice`), /// this is interpreted as a sub-slice pattern semantically. /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`. - fn lower_pat_slice(&mut self, pats: &[Box]) -> hir::PatKind<'hir> { + fn lower_pat_slice(&mut self, pats: &[Pat]) -> hir::PatKind<'hir> { let mut before = Vec::new(); let mut after = Vec::new(); let mut slice = None; diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 3fcf9da945070..36ce1b7204467 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1507,7 +1507,7 @@ impl<'a> TraitDef<'a> { struct_def: &'a VariantData, prefixes: &[String], by_ref: ByRef, - ) -> ThinVec> { + ) -> ThinVec { prefixes .iter() .map(|prefix| { @@ -1543,7 +1543,7 @@ impl<'a> TraitDef<'a> { attrs: ast::AttrVec::new(), id: ast::DUMMY_NODE_ID, span: pat.span.with_ctxt(self.span.ctxt()), - pat, + pat: Box::new(pat), is_placeholder: false, } }) diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index 34faafdc07c61..8b64bdf02d3b7 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -32,7 +32,7 @@ fn parse_pat_ty<'a>( let pat = pat_to_ty_pat( cx, - *parser.parse_pat_no_top_guard( + parser.parse_pat_no_top_guard( None, RecoverComma::No, RecoverColon::No, @@ -44,14 +44,14 @@ fn parse_pat_ty<'a>( parser.unexpected()?; } - Ok((ty, pat)) + Ok((ty, Box::new(pat))) } -fn ty_pat(kind: TyPatKind, span: Span) -> Box { - Box::new(TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None }) +fn ty_pat(kind: TyPatKind, span: Span) -> TyPat { + TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None } } -fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> Box { +fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> TyPat { let kind = match pat.kind { ast::PatKind::Range(start, end, include_end) => TyPatKind::Range( start.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), @@ -59,7 +59,7 @@ fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> Box { include_end, ), ast::PatKind::Or(variants) => { - TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, *pat)).collect()) + TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat)).collect()) } ast::PatKind::Err(guar) => TyPatKind::Err(guar), _ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index c3e86ec0614c7..55541cdf4d7e1 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -233,7 +233,7 @@ impl<'a> ExtCtxt<'a> { }; let local = Box::new(ast::Local { super_: None, - pat, + pat: Box::new(pat), ty, id: ast::DUMMY_NODE_ID, kind: LocalKind::Init(ex), @@ -249,7 +249,7 @@ impl<'a> ExtCtxt<'a> { pub fn stmt_let_type_only(&self, span: Span, ty: Box) -> ast::Stmt { let local = Box::new(ast::Local { super_: None, - pat: self.pat_wild(span), + pat: Box::new(self.pat_wild(span)), ty: Some(ty), id: ast::DUMMY_NODE_ID, kind: LocalKind::Decl, @@ -528,16 +528,16 @@ impl<'a> ExtCtxt<'a> { self.expr_match(sp, head, thin_vec![ok_arm, err_arm]) } - pub fn pat(&self, span: Span, kind: PatKind) -> Box { - Box::new(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None }) + pub fn pat(&self, span: Span, kind: PatKind) -> ast::Pat { + ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None } } - pub fn pat_wild(&self, span: Span) -> Box { + pub fn pat_wild(&self, span: Span) -> ast::Pat { self.pat(span, PatKind::Wild) } - pub fn pat_lit(&self, span: Span, expr: Box) -> Box { + pub fn pat_lit(&self, span: Span, expr: Box) -> ast::Pat { self.pat(span, PatKind::Expr(expr)) } - pub fn pat_ident(&self, span: Span, ident: Ident) -> Box { + pub fn pat_ident(&self, span: Span, ident: Ident) -> ast::Pat { self.pat_ident_binding_mode(span, ident, ast::BindingMode::NONE) } @@ -546,19 +546,19 @@ impl<'a> ExtCtxt<'a> { span: Span, ident: Ident, ann: ast::BindingMode, - ) -> Box { + ) -> ast::Pat { let pat = PatKind::Ident(ann, ident.with_span_pos(span), None); self.pat(span, pat) } - pub fn pat_path(&self, span: Span, path: ast::Path) -> Box { + pub fn pat_path(&self, span: Span, path: ast::Path) -> ast::Pat { self.pat(span, PatKind::Path(None, path)) } pub fn pat_tuple_struct( &self, span: Span, path: ast::Path, - subpats: ThinVec>, - ) -> Box { + subpats: ThinVec, + ) -> ast::Pat { self.pat(span, PatKind::TupleStruct(None, path, subpats)) } pub fn pat_struct( @@ -566,23 +566,23 @@ impl<'a> ExtCtxt<'a> { span: Span, path: ast::Path, field_pats: ThinVec, - ) -> Box { + ) -> ast::Pat { self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None)) } - pub fn pat_tuple(&self, span: Span, pats: ThinVec>) -> Box { + pub fn pat_tuple(&self, span: Span, pats: ThinVec) -> ast::Pat { self.pat(span, PatKind::Tuple(pats)) } - pub fn pat_some(&self, span: Span, pat: Box) -> Box { + pub fn pat_some(&self, span: Span, pat: ast::Pat) -> ast::Pat { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, thin_vec![pat]) } - pub fn arm(&self, span: Span, pat: Box, expr: Box) -> ast::Arm { + pub fn arm(&self, span: Span, pat: ast::Pat, expr: Box) -> ast::Arm { ast::Arm { attrs: AttrVec::new(), - pat, + pat: Box::new(pat), guard: None, body: Some(expr), span, @@ -661,11 +661,11 @@ impl<'a> ExtCtxt<'a> { } pub fn param(&self, span: Span, ident: Ident, ty: Box) -> ast::Param { - let arg_pat = self.pat_ident(span, ident); + let pat = Box::new(self.pat_ident(span, ident)); ast::Param { attrs: AttrVec::default(), id: ast::DUMMY_NODE_ID, - pat: arg_pat, + pat, span, ty, is_placeholder: false, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 3dfa3cdcc3560..8031e11afc752 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1152,12 +1152,12 @@ pub fn parse_ast_fragment<'a>( } } AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?), - AstFragmentKind::Pat => AstFragment::Pat(this.parse_pat_allow_top_guard( + AstFragmentKind::Pat => AstFragment::Pat(Box::new(this.parse_pat_allow_top_guard( None, RecoverComma::No, RecoverColon::Yes, CommaRecoveryMode::LikelyTuple, - )?), + )?)), AstFragmentKind::Crate => AstFragment::Crate(this.parse_crate_mod()?), AstFragmentKind::Arms | AstFragmentKind::ExprFields diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 8b87e4d969034..c36cd610c6a59 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -73,6 +73,16 @@ pub(super) trait RecoverQPath: Sized + 'static { fn recovered(qself: Option>, path: ast::Path) -> Self; } +impl RecoverQPath for Box { + const PATH_STYLE: PathStyle = T::PATH_STYLE; + fn to_ty(&self) -> Option> { + T::to_ty(self) + } + fn recovered(qself: Option>, path: ast::Path) -> Self { + Box::new(T::recovered(qself, path)) + } +} + impl RecoverQPath for Ty { const PATH_STYLE: PathStyle = PathStyle::Type; fn to_ty(&self) -> Option> { @@ -1833,17 +1843,19 @@ impl<'a> Parser<'a> { /// tail, and combines them into a `::AssocItem` expression/pattern/type. pub(super) fn maybe_recover_from_bad_qpath( &mut self, - base: Box, - ) -> PResult<'a, Box> { - if !self.may_recover() { - return Ok(base); + base: T, + ) -> PResult<'a, T> { + // Do not add `::` to expected tokens. + if self.may_recover() && self.token == token::PathSep { + return self.recover_from_bad_qpath(base); } + Ok(base) + } - // Do not add `::` to expected tokens. - if self.token == token::PathSep { - if let Some(ty) = base.to_ty() { - return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty); - } + #[cold] + fn recover_from_bad_qpath(&mut self, base: T) -> PResult<'a, T> { + if let Some(ty) = base.to_ty() { + return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty); } Ok(base) } @@ -1854,7 +1866,7 @@ impl<'a> Parser<'a> { &mut self, ty_span: Span, ty: Box, - ) -> PResult<'a, Box> { + ) -> PResult<'a, T> { self.expect(exp!(PathSep))?; let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None }; @@ -1867,7 +1879,7 @@ impl<'a> Parser<'a> { }); let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`. - Ok(Box::new(T::recovered(Some(Box::new(QSelf { ty, path_span, position: 0 })), path))) + Ok(T::recovered(Some(Box::new(QSelf { ty, path_span, position: 0 })), path)) } /// This function gets called in places where a semicolon is NOT expected and if there's a @@ -2360,6 +2372,7 @@ impl<'a> Parser<'a> { None } + #[cold] pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (Box, Box)> { let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?; self.expect(exp!(Colon))?; @@ -2740,11 +2753,12 @@ impl<'a> Parser<'a> { /// Some special error handling for the "top-level" patterns in a match arm, /// `for` loop, `let`, &c. (in contrast to subpatterns within such). - pub(crate) fn maybe_recover_colon_colon_in_pat_typo( + #[cold] + pub(crate) fn recover_colon_colon_in_pat_typo( &mut self, - mut first_pat: Box, + mut first_pat: Pat, expected: Option, - ) -> Box { + ) -> Pat { if token::Colon != self.token.kind { return first_pat; } @@ -2925,7 +2939,11 @@ impl<'a> Parser<'a> { if self.token != token::Comma { return Ok(()); } + self.recover_unexpected_comma(lo, rt) + } + #[cold] + fn recover_unexpected_comma(&mut self, lo: Span, rt: CommaRecoveryMode) -> PResult<'a, ()> { // An unexpected comma after a top-level pattern is a clue that the // user (perhaps more accustomed to some other language) forgot the // parentheses in what should have been a tuple pattern; return a diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8046abcd70bd0..57bd0d500d5af 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2587,7 +2587,7 @@ impl<'a> Parser<'a> { let lo = self.token.span; let attrs = self.parse_outer_attributes()?; self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { - let pat = this.parse_pat_no_top_alt(Some(Expected::ParameterName), None)?; + let pat = Box::new(this.parse_pat_no_top_alt(Some(Expected::ParameterName), None)?); let ty = if this.eat(exp!(Colon)) { this.parse_ty()? } else { @@ -2781,7 +2781,7 @@ impl<'a> Parser<'a> { let (expr, _) = self.parse_expr_assoc_with(Bound::Excluded(prec_let_scrutinee_needs_par()), attrs)?; let span = lo.to(expr.span); - Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span, recovered))) + Ok(self.mk_expr(span, ExprKind::Let(Box::new(pat), expr, span, recovered))) } /// Parses an `else { ... }` expression (`else` token already eaten). @@ -2897,7 +2897,7 @@ impl<'a> Parser<'a> { } // Public to use it for custom `for` expressions in rustfmt forks like https://github.com/tucant/rustfmt - pub fn parse_for_head(&mut self) -> PResult<'a, (Box, Box)> { + pub fn parse_for_head(&mut self) -> PResult<'a, (Pat, Box)> { let begin_paren = if self.token == token::OpenParen { // Record whether we are about to parse `for (`. // This is used below for recovery in case of `for ( $stuff ) $block` @@ -2974,6 +2974,7 @@ impl<'a> Parser<'a> { let kind = if is_await { ForLoopKind::ForAwait } else { ForLoopKind::For }; let (pat, expr) = self.parse_for_head()?; + let pat = Box::new(pat); // Recover from missing expression in `for` loop if matches!(expr.kind, ExprKind::Block(..)) && self.token.kind != token::OpenBrace @@ -3142,7 +3143,7 @@ impl<'a> Parser<'a> { // Always push at least one arm to make the match non-empty arms.push(Arm { attrs: Default::default(), - pat: self.mk_pat(span, ast::PatKind::Err(guar)), + pat: Box::new(self.mk_pat(span, ast::PatKind::Err(guar))), guard: None, body: Some(self.mk_expr_err(span, guar)), span, @@ -3246,6 +3247,7 @@ impl<'a> Parser<'a> { self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; let (pat, guard) = this.parse_match_arm_pat_and_guard()?; + let pat = Box::new(pat); let span_before_body = this.prev_token.span; let arm_body; @@ -3468,7 +3470,7 @@ impl<'a> Parser<'a> { Ok(Some(cond)) } - fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Box, Option>)> { + fn parse_match_arm_pat_and_guard(&mut self) -> PResult<'a, (Pat, Option>)> { if self.token == token::OpenParen { let left = self.token.span; let pat = self.parse_pat_no_top_guard( diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index eb264f59fedbe..aa03d5956cd23 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -3111,7 +3111,7 @@ impl<'a> Parser<'a> { match ty { Ok(ty) => { let pat = this.mk_pat(ty.span, PatKind::Missing); - (pat, ty) + (Box::new(pat), ty) } // If this is a C-variadic argument and we hit an error, return the error. Err(err) if this.token == token::DotDotDot => return Err(err), diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 42eb07858c2fe..ea2b896f5fb9c 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -142,7 +142,8 @@ impl<'a> Parser<'a> { RecoverColon::No, CommaRecoveryMode::EitherTupleOrPipe, ), - })?, + }) + .map(Box::new)?, pat_kind, )), NonterminalKind::Expr(expr_kind) => { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index fda19d62bc774..4f522d57e4140 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -107,7 +107,7 @@ impl<'a> Parser<'a> { rc: RecoverComma, ra: RecoverColon, rt: CommaRecoveryMode, - ) -> PResult<'a, Box> { + ) -> PResult<'a, Pat> { let pat = self.parse_pat_no_top_guard(expected, rc, ra, rt)?; if self.eat_keyword(exp!(If)) { @@ -115,7 +115,7 @@ impl<'a> Parser<'a> { // Feature-gate guard patterns self.psess.gated_spans.gate(sym::guard_patterns, cond.span); let span = pat.span.to(cond.span); - Ok(self.mk_pat(span, PatKind::Guard(pat, cond))) + Ok(self.mk_pat(span, PatKind::Guard(Box::new(pat), cond))) } else { Ok(pat) } @@ -130,7 +130,7 @@ impl<'a> Parser<'a> { &mut self, expected: Option, syntax_loc: Option, - ) -> PResult<'a, Box> { + ) -> PResult<'a, Pat> { self.parse_pat_with_range_pat(true, expected, syntax_loc) } @@ -149,7 +149,7 @@ impl<'a> Parser<'a> { rc: RecoverComma, ra: RecoverColon, rt: CommaRecoveryMode, - ) -> PResult<'a, Box> { + ) -> PResult<'a, Pat> { self.parse_pat_no_top_guard_inner(expected, rc, ra, rt, None).map(|(pat, _)| pat) } @@ -162,7 +162,7 @@ impl<'a> Parser<'a> { ra: RecoverColon, rt: CommaRecoveryMode, syntax_loc: Option, - ) -> PResult<'a, (Box, bool)> { + ) -> PResult<'a, (Pat, bool)> { // Keep track of whether we recovered from a trailing vert so that we can avoid duplicated // suggestions (which bothers rustfix). // @@ -199,8 +199,8 @@ impl<'a> Parser<'a> { // This complicated procedure is done purely for diagnostics UX. // Check if the user wrote `foo:bar` instead of `foo::bar`. - if ra == RecoverColon::Yes { - first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected); + if ra == RecoverColon::Yes && token::Colon == self.token.kind { + first_pat = self.recover_colon_colon_in_pat_typo(first_pat, expected); } if let Some(leading_vert_span) = leading_vert_span { @@ -263,6 +263,7 @@ impl<'a> Parser<'a> { CommaRecoveryMode::LikelyTuple, Some(syntax_loc), )?; + let pat = Box::new(pat); let colon = self.eat(exp!(Colon)); if let PatKind::Or(pats) = &pat.kind { @@ -686,7 +687,7 @@ impl<'a> Parser<'a> { PatVisitor { parser: self, stmt, arm: None, field: None }.visit_stmt(stmt); } - fn eat_metavar_pat(&mut self) -> Option> { + fn eat_metavar_pat(&mut self) -> Option { // Must try both kinds of pattern nonterminals. if let Some(pat) = self.eat_metavar_seq_with_matcher( |mv_kind| matches!(mv_kind, MetaVarKind::Pat(PatParam { .. })), @@ -714,7 +715,7 @@ impl<'a> Parser<'a> { allow_range_pat: bool, expected: Option, syntax_loc: Option, - ) -> PResult<'a, Box> { + ) -> PResult<'a, Pat> { maybe_recover_from_interpolated_ty_qpath!(self, true); if let Some(pat) = self.eat_metavar_pat() { @@ -873,9 +874,12 @@ impl<'a> Parser<'a> { } }; - let pat = self.mk_pat(lo.to(self.prev_token.span), pat); - let pat = self.maybe_recover_from_bad_qpath(pat)?; - let pat = self.recover_intersection_pat(pat)?; + let mut pat = self.mk_pat(lo.to(self.prev_token.span), pat); + + pat = self.maybe_recover_from_bad_qpath(pat)?; + if self.eat_noexpect(&token::At) { + pat = self.recover_intersection_pat(pat)?; + } if !allow_range_pat { self.ban_pat_range_if_ambiguous(&pat) @@ -921,14 +925,8 @@ impl<'a> Parser<'a> { /// e.g. [F#][and] where they are called AND-patterns. /// /// [and]: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching - fn recover_intersection_pat(&mut self, lhs: Box) -> PResult<'a, Box> { - if self.token != token::At { - // Next token is not `@` so it's not going to be an intersection pattern. - return Ok(lhs); - } - - // At this point we attempt to parse `@ $pat_rhs` and emit an error. - self.bump(); // `@` + #[cold] + fn recover_intersection_pat(&mut self, lhs: Pat) -> PResult<'a, Pat> { let mut rhs = self.parse_pat_no_top_alt(None, None)?; let whole_span = lhs.span.to(rhs.span); @@ -937,7 +935,7 @@ impl<'a> Parser<'a> { let lhs_span = lhs.span; // Move the LHS into the RHS as a subpattern. // The RHS is now the full pattern. - *sub = Some(lhs); + *sub = Some(Box::new(lhs)); self.dcx().emit_err(PatternOnWrongSideOfAt { whole_span, @@ -994,7 +992,7 @@ impl<'a> Parser<'a> { let mutbl = self.parse_mutability(); let subpat = self.parse_pat_with_range_pat(false, expected, None)?; - Ok(PatKind::Ref(subpat, mutbl)) + Ok(PatKind::Ref(Box::new(subpat), mutbl)) } /// Parse a tuple or parenthesis pattern. @@ -1052,7 +1050,7 @@ impl<'a> Parser<'a> { } // (pat) with optional parentheses - _ => PatKind::Paren(pat), + _ => PatKind::Paren(Box::new(pat)), } } else { PatKind::Tuple(fields) @@ -1103,7 +1101,7 @@ impl<'a> Parser<'a> { /// Turn all by-value immutable bindings in a pattern into mutable bindings. /// Returns `true` if any change was made. - fn make_all_value_bindings_mutable(pat: &mut Box) -> bool { + fn make_all_value_bindings_mutable(pat: &mut Pat) -> bool { struct AddMut(bool); impl MutVisitor for AddMut { fn visit_pat(&mut self, pat: &mut Pat) { @@ -1159,7 +1157,7 @@ impl<'a> Parser<'a> { &mut self, err: Diag<'a>, expected: Option, - ) -> PResult<'a, Box> { + ) -> PResult<'a, Pat> { err.cancel(); let expected = Expected::to_string_or_fallback(expected); @@ -1362,7 +1360,7 @@ impl<'a> Parser<'a> { } let sub = if self.eat(exp!(At)) { - Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?) + Some(Box::new(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?)) } else { None }; @@ -1451,12 +1449,14 @@ impl<'a> Parser<'a> { self.parse_builtin(|self_, _lo, ident| { Ok(match ident.name { // builtin#deref(PAT) - sym::deref => Some(ast::PatKind::Deref(self_.parse_pat_allow_top_guard( - None, - RecoverComma::Yes, - RecoverColon::Yes, - CommaRecoveryMode::LikelyTuple, - )?)), + sym::deref => { + Some(ast::PatKind::Deref(Box::new(self_.parse_pat_allow_top_guard( + None, + RecoverComma::Yes, + RecoverColon::Yes, + CommaRecoveryMode::LikelyTuple, + )?))) + } _ => None, }) }) @@ -1478,14 +1478,14 @@ impl<'a> Parser<'a> { // We cannot use `parse_pat_ident()` since it will complain `box` // is not an identifier. let sub = if self.eat(exp!(At)) { - Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?) + Some(Box::new(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?)) } else { None }; Ok(PatKind::Ident(BindingMode::NONE, Ident::new(kw::Box, box_span), sub)) } else { - let pat = self.parse_pat_with_range_pat(false, None, None)?; + let pat = Box::new(self.parse_pat_with_range_pat(false, None, None)?); self.psess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span)); Ok(PatKind::Box(pat)) } @@ -1745,14 +1745,17 @@ impl<'a> Parser<'a> { hi = self.prev_token.span; let ann = BindingMode(by_ref, mutability); let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname); - let subpat = - if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat }; + let subpat = if is_box { + self.mk_pat(lo.to(hi), PatKind::Box(Box::new(fieldpat))) + } else { + fieldpat + }; (subpat, fieldname, true) }; Ok(PatField { ident: fieldname, - pat: subpat, + pat: Box::new(subpat), is_shorthand, attrs, id: ast::DUMMY_NODE_ID, @@ -1761,11 +1764,11 @@ impl<'a> Parser<'a> { }) } - pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingMode, ident: Ident) -> Box { + pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingMode, ident: Ident) -> Pat { self.mk_pat(span, PatKind::Ident(ann, ident, None)) } - pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> Box { - Box::new(Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None }) + pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> Pat { + Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None } } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4d4acc60ca804..8c6e9f6fb3a40 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3664,7 +3664,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { /// pattern as a whole counts as a never pattern (since it's definitionallly unreachable). fn compute_and_check_or_pat_binding_map( &mut self, - pats: &[Box], + pats: &[Pat], ) -> Result, IsNeverPattern> { let mut missing_vars = FxIndexMap::default(); let mut inconsistent_vars = FxIndexMap::default(); @@ -3679,11 +3679,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .collect::>(); // 2) Record any missing bindings or binding mode inconsistencies. - for (map_outer, pat_outer) in not_never_pats.iter() { + for &(ref map_outer, pat_outer) in not_never_pats.iter() { // Check against all arms except for the same pattern which is always self-consistent. let inners = not_never_pats.iter().filter(|(_, pat)| pat.id != pat_outer.id); - for (map, pat) in inners { + for &(ref map, pat) in inners { for (&name, binding_inner) in map { match map_outer.get(&name) { None => { @@ -3695,8 +3695,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { target: Default::default(), could_be_path: name.as_str().starts_with(char::is_uppercase), }); - binding_error.origin.push((binding_inner.span, (***pat).clone())); - binding_error.target.push((***pat_outer).clone()); + binding_error.origin.push((binding_inner.span, pat.clone())); + binding_error.target.push(pat_outer.clone()); } Some(binding_outer) => { if binding_outer.annotation != binding_inner.annotation { diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index f3410c98973f5..5dd67e35eb18a 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -223,7 +223,7 @@ macro_rules! always_pat { /// Focus on `focus_idx` in `alternatives`, /// attempting to extend it with elements of the same constructor `C` /// in `alternatives[focus_idx + 1..]`. -fn transform_with_focus_on_idx(alternatives: &mut ThinVec>, focus_idx: usize) -> bool { +fn transform_with_focus_on_idx(alternatives: &mut ThinVec, focus_idx: usize) -> bool { // Extract the kind; we'll need to make some changes in it. let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild); // We'll focus on `alternatives[focus_idx]`, @@ -251,20 +251,20 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec>, focus_idx: Box(target) => extend_with_matching( target, start, alternatives, |k| matches!(k, Box(_)), - |k| always_pat!(k, Box(p) => p), + |k| always_pat!(k, Box(p) => *p), ), // Transform `&mut x | ... | &mut y` into `&mut (x | y)`. Ref(target, Mutability::Mut) => extend_with_matching( target, start, alternatives, |k| matches!(k, Ref(_, Mutability::Mut)), - |k| always_pat!(k, Ref(p, _) => p), + |k| always_pat!(k, Ref(p, _) => *p), ), // Transform `b @ p0 | ... b @ p1` into `b @ (p0 | p1)`. Ident(b1, i1, Some(target)) => extend_with_matching( target, start, alternatives, // Binding names must match. |k| matches!(k, Ident(b2, i2, Some(_)) if b1 == b2 && eq_id(*i1, *i2)), - |k| always_pat!(k, Ident(_, _, Some(p)) => p), + |k| always_pat!(k, Ident(_, _, Some(p)) => *p), ), // Transform `[pre, x, post] | ... | [pre, y, post]` into `[pre, x | y, post]`. Slice(ps1) => extend_with_matching_product( @@ -309,7 +309,7 @@ fn extend_with_struct_pat( fps1: &mut [ast::PatField], rest1: ast::PatFieldsRest, start: usize, - alternatives: &mut ThinVec>, + alternatives: &mut ThinVec, ) -> bool { (0..fps1.len()).any(|idx| { let pos_in_2 = Cell::new(None); // The element `k`. @@ -339,7 +339,7 @@ fn extend_with_struct_pat( })) }, // Extract `p2_k`. - |k| always_pat!(k, Struct(_, _, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat), + |k| always_pat!(k, Struct(_, _, mut fps, _) => *fps.swap_remove(pos_in_2.take().unwrap()).pat), ); extend_with_tail_or(&mut fps1[idx].pat, tail_or) }) @@ -351,11 +351,11 @@ fn extend_with_struct_pat( /// while also requiring `ps1[..n] ~ ps2[..n]` (pre) and `ps1[n + 1..] ~ ps2[n + 1..]` (post), /// where `~` denotes semantic equality. fn extend_with_matching_product( - targets: &mut [Box], + targets: &mut [Pat], start: usize, - alternatives: &mut ThinVec>, - predicate: impl Fn(&PatKind, &[Box], usize) -> bool, - extract: impl Fn(PatKind) -> ThinVec>, + alternatives: &mut ThinVec, + predicate: impl Fn(&PatKind, &[Pat], usize) -> bool, + extract: impl Fn(PatKind) -> ThinVec, ) -> bool { (0..targets.len()).any(|idx| { let tail_or = drain_matching( @@ -382,14 +382,14 @@ fn take_pat(from: &mut Pat) -> Pat { /// Extend `target` as an or-pattern with the alternatives /// in `tail_or` if there are any and return if there were. -fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec>) -> bool { - fn extend(target: &mut Pat, mut tail_or: ThinVec>) { +fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec) -> bool { + fn extend(target: &mut Pat, mut tail_or: ThinVec) { match target { // On an existing or-pattern in the target, append to it. Pat { kind: Or(ps), .. } => ps.append(&mut tail_or), // Otherwise convert the target to an or-pattern. target => { - let mut init_or = thin_vec![Box::new(take_pat(target))]; + let mut init_or = thin_vec![take_pat(target)]; init_or.append(&mut tail_or); target.kind = Or(init_or); }, @@ -408,10 +408,10 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec>) -> bool { // Only elements beginning with `start` are considered for extraction. fn drain_matching( start: usize, - alternatives: &mut ThinVec>, + alternatives: &mut ThinVec, predicate: impl Fn(&PatKind) -> bool, - extract: impl Fn(PatKind) -> Box, -) -> ThinVec> { + extract: impl Fn(PatKind) -> Pat, +) -> ThinVec { let mut tail_or = ThinVec::new(); let mut idx = 0; @@ -443,15 +443,15 @@ fn drain_matching( fn extend_with_matching( target: &mut Pat, start: usize, - alternatives: &mut ThinVec>, + alternatives: &mut ThinVec, predicate: impl Fn(&PatKind) -> bool, - extract: impl Fn(PatKind) -> Box, + extract: impl Fn(PatKind) -> Pat, ) -> bool { extend_with_tail_or(target, drain_matching(start, alternatives, predicate, extract)) } /// Are the patterns in `ps1` and `ps2` equal save for `ps1[idx]` compared to `ps2[idx]`? -fn eq_pre_post(ps1: &[Box], ps2: &[Box], idx: usize) -> bool { +fn eq_pre_post(ps1: &[Pat], ps2: &[Pat], idx: usize) -> bool { ps1.len() == ps2.len() && ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`. && over(&ps1[..idx], &ps2[..idx], |l, r| eq_pat(l, r)) diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index 724d7a09e4afa..c063990dfa0b1 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -61,7 +61,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { Pat, NonterminalKind::Pat(PatParam { inferred: false }), |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None), - |x: Box| Some(x) + |x: ast::Pat| Some(Box::new(x)) ); // `parse_item` returns `Option>`. parse_macro_arg!( diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index 848bd0766e786..fa9a3e33914b6 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -504,7 +504,7 @@ impl Rewrite for PatField { #[derive(Debug)] pub(crate) enum TuplePatField<'a> { - Pat(&'a Box), + Pat(&'a ast::Pat), Dotdot(Span), } @@ -561,7 +561,7 @@ pub(crate) fn can_be_overflowed_pat( } fn rewrite_tuple_pat( - pats: &[Box], + pats: &[ast::Pat], path_str: Option, span: Span, context: &RewriteContext<'_>,