Skip to content

Commit b92ccaf

Browse files
authored
Unrolled build for rust-lang#134228
Rollup merge of rust-lang#134228 - oli-obk:pat-lit-path, r=compiler-errors Exhaustively handle expressions in patterns We currently have this invariant in HIR that a `PatKind::Lit` or a `PatKind::Range` only contains * `ExprKind::Lit` * `ExprKind::UnOp(Neg, ExprKind::Lit)` * `ExprKind::Path` * `ExprKind::ConstBlock` So I made `PatKind::Lit` and `PatKind::Range` stop containing `Expr`, and instead created a `PatLit` type whose `kind` enum only contains those variants. The only place code got more complicated was in clippy, as it couldn't share as much anymore with `Expr` handling It may be interesting on merging `ExprKind::{Path,Lit,ConstBlock}` in the future and using the same `PatLit` type (under a new name). Then it should also be easier to eliminate any and all `UnOp(Neg, Lit) | Lit` matching that we have across the compiler. Some day we should fold the negation into the literal itself and just store it on the numeric literals
2 parents a580b5c + 4a8773a commit b92ccaf

File tree

58 files changed

+523
-273
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+523
-273
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ impl Pat {
623623
PatKind::Wild
624624
| PatKind::Rest
625625
| PatKind::Never
626-
| PatKind::Lit(_)
626+
| PatKind::Expr(_)
627627
| PatKind::Range(..)
628628
| PatKind::Ident(..)
629629
| PatKind::Path(..)
@@ -801,8 +801,8 @@ pub enum PatKind {
801801
/// A reference pattern (e.g., `&mut (a, b)`).
802802
Ref(P<Pat>, Mutability),
803803

804-
/// A literal.
805-
Lit(P<Expr>),
804+
/// A literal, const block or path.
805+
Expr(P<Expr>),
806806

807807
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
808808
Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,7 @@ pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) {
15121512
vis.visit_ident(ident);
15131513
visit_opt(sub, |sub| vis.visit_pat(sub));
15141514
}
1515-
PatKind::Lit(e) => vis.visit_expr(e),
1515+
PatKind::Expr(e) => vis.visit_expr(e),
15161516
PatKind::TupleStruct(qself, path, elems) => {
15171517
vis.visit_qself(qself);
15181518
vis.visit_path(path);

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res
680680
try_visit!(visitor.visit_ident(ident));
681681
visit_opt!(visitor, visit_pat, optional_subpattern);
682682
}
683-
PatKind::Lit(expression) => try_visit!(visitor.visit_expr(expression)),
683+
PatKind::Expr(expression) => try_visit!(visitor.visit_expr(expression)),
684684
PatKind::Range(lower_bound, upper_bound, _end) => {
685685
visit_opt!(visitor, visit_expr, lower_bound);
686686
visit_opt!(visitor, visit_expr, upper_bound);

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
102102

103103
let kind = match &e.kind {
104104
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
105-
ExprKind::ConstBlock(c) => {
106-
let c = self.with_new_scopes(c.value.span, |this| {
107-
let def_id = this.local_def_id(c.id);
108-
hir::ConstBlock {
109-
def_id,
110-
hir_id: this.lower_node_id(c.id),
111-
body: this.lower_const_body(c.value.span, Some(&c.value)),
112-
}
113-
});
114-
hir::ExprKind::ConstBlock(c)
115-
}
105+
ExprKind::ConstBlock(c) => hir::ExprKind::ConstBlock(self.lower_const_block(c)),
116106
ExprKind::Repeat(expr, count) => {
117107
let expr = self.lower_expr(expr);
118108
let count = self.lower_array_length_to_const_arg(count);
@@ -153,18 +143,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
153143
let ohs = self.lower_expr(ohs);
154144
hir::ExprKind::Unary(op, ohs)
155145
}
156-
ExprKind::Lit(token_lit) => {
157-
let lit_kind = match LitKind::from_token_lit(*token_lit) {
158-
Ok(lit_kind) => lit_kind,
159-
Err(err) => {
160-
let guar =
161-
report_lit_error(&self.tcx.sess.psess, err, *token_lit, e.span);
162-
LitKind::Err(guar)
163-
}
164-
};
165-
let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind));
166-
hir::ExprKind::Lit(lit)
167-
}
146+
ExprKind::Lit(token_lit) => hir::ExprKind::Lit(self.lower_lit(token_lit, e.span)),
168147
ExprKind::IncludedBytes(bytes) => {
169148
let lit = self.arena.alloc(respan(
170149
self.lower_span(e.span),
@@ -403,6 +382,32 @@ impl<'hir> LoweringContext<'_, 'hir> {
403382
})
404383
}
405384

385+
pub(crate) fn lower_const_block(&mut self, c: &AnonConst) -> hir::ConstBlock {
386+
self.with_new_scopes(c.value.span, |this| {
387+
let def_id = this.local_def_id(c.id);
388+
hir::ConstBlock {
389+
def_id,
390+
hir_id: this.lower_node_id(c.id),
391+
body: this.lower_const_body(c.value.span, Some(&c.value)),
392+
}
393+
})
394+
}
395+
396+
pub(crate) fn lower_lit(
397+
&mut self,
398+
token_lit: &token::Lit,
399+
span: Span,
400+
) -> &'hir Spanned<LitKind> {
401+
let lit_kind = match LitKind::from_token_lit(*token_lit) {
402+
Ok(lit_kind) => lit_kind,
403+
Err(err) => {
404+
let guar = report_lit_error(&self.tcx.sess.psess, err, *token_lit, span);
405+
LitKind::Err(guar)
406+
}
407+
};
408+
self.arena.alloc(respan(self.lower_span(span), lit_kind))
409+
}
410+
406411
fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
407412
match u {
408413
UnOp::Deref => hir::UnOp::Deref,

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
209209
});
210210
}
211211

212+
fn visit_pat_expr(&mut self, expr: &'hir PatExpr<'hir>) {
213+
self.insert(expr.span, expr.hir_id, Node::PatExpr(expr));
214+
215+
self.with_parent(expr.hir_id, |this| {
216+
intravisit::walk_pat_expr(this, expr);
217+
});
218+
}
219+
212220
fn visit_pat_field(&mut self, field: &'hir PatField<'hir>) {
213221
self.insert(field.span, field.hir_id, Node::PatField(field));
214222
self.with_parent(field.hir_id, |this| {

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#![doc(rust_logo)]
3636
#![feature(assert_matches)]
3737
#![feature(box_patterns)]
38+
#![feature(if_let_guard)]
3839
#![feature(let_chains)]
3940
#![feature(rustdoc_internals)]
4041
#![warn(unreachable_pub)]

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
use std::sync::Arc;
2+
13
use rustc_ast::ptr::P;
24
use rustc_ast::*;
35
use rustc_data_structures::stack::ensure_sufficient_stack;
46
use rustc_hir as hir;
57
use rustc_hir::def::Res;
6-
use rustc_span::source_map::Spanned;
8+
use rustc_middle::span_bug;
9+
use rustc_span::source_map::{Spanned, respan};
710
use rustc_span::{Ident, Span};
811

912
use super::errors::{
@@ -35,8 +38,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
3538
lower_sub,
3639
);
3740
}
38-
PatKind::Lit(e) => {
39-
break hir::PatKind::Lit(self.lower_expr_within_pat(e, false));
41+
PatKind::Expr(e) => {
42+
break hir::PatKind::Expr(self.lower_expr_within_pat(e, false));
4043
}
4144
PatKind::TupleStruct(qself, path, pats) => {
4245
let qpath = self.lower_qpath(
@@ -367,24 +370,54 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
367370
// }
368371
// m!(S);
369372
// ```
370-
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> {
371-
match &expr.kind {
372-
ExprKind::Lit(..)
373-
| ExprKind::ConstBlock(..)
374-
| ExprKind::IncludedBytes(..)
375-
| ExprKind::Err(_)
376-
| ExprKind::Dummy => {}
377-
ExprKind::Path(..) if allow_paths => {}
378-
ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
373+
fn lower_expr_within_pat(
374+
&mut self,
375+
expr: &Expr,
376+
allow_paths: bool,
377+
) -> &'hir hir::PatExpr<'hir> {
378+
let err = |guar| hir::PatExprKind::Lit {
379+
lit: self.arena.alloc(respan(self.lower_span(expr.span), LitKind::Err(guar))),
380+
negated: false,
381+
};
382+
let kind = match &expr.kind {
383+
ExprKind::Lit(lit) => {
384+
hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: false }
385+
}
386+
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)),
387+
ExprKind::IncludedBytes(bytes) => hir::PatExprKind::Lit {
388+
lit: self.arena.alloc(respan(
389+
self.lower_span(expr.span),
390+
LitKind::ByteStr(Arc::clone(bytes), StrStyle::Cooked),
391+
)),
392+
negated: false,
393+
},
394+
ExprKind::Err(guar) => err(*guar),
395+
ExprKind::Dummy => span_bug!(expr.span, "lowered ExprKind::Dummy"),
396+
ExprKind::Path(qself, path) if allow_paths => hir::PatExprKind::Path(self.lower_qpath(
397+
expr.id,
398+
qself,
399+
path,
400+
ParamMode::Optional,
401+
AllowReturnTypeNotation::No,
402+
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
403+
None,
404+
)),
405+
ExprKind::Unary(UnOp::Neg, inner) if let ExprKind::Lit(lit) = &inner.kind => {
406+
hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: true }
407+
}
379408
_ => {
380409
let pattern_from_macro = expr.is_approximately_pattern();
381410
let guar = self.dcx().emit_err(ArbitraryExpressionInPattern {
382411
span: expr.span,
383412
pattern_from_macro_note: pattern_from_macro,
384413
});
385-
return self.arena.alloc(self.expr_err(expr.span, guar));
414+
err(guar)
386415
}
387-
}
388-
self.lower_expr(expr)
416+
};
417+
self.arena.alloc(hir::PatExpr {
418+
hir_id: self.lower_node_id(expr.id),
419+
span: expr.span,
420+
kind,
421+
})
389422
}
390423
}

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ impl<'a> State<'a> {
17011701
self.print_pat(inner);
17021702
}
17031703
}
1704-
PatKind::Lit(e) => self.print_expr(e, FixupContext::default()),
1704+
PatKind::Expr(e) => self.print_expr(e, FixupContext::default()),
17051705
PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => {
17061706
if let Some(e) = begin {
17071707
self.print_expr(e, FixupContext::default());

compiler/rustc_expand/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ impl MacResult for MacEager {
522522
return Some(P(ast::Pat {
523523
id: ast::DUMMY_NODE_ID,
524524
span: e.span,
525-
kind: PatKind::Lit(e),
525+
kind: PatKind::Expr(e),
526526
tokens: None,
527527
}));
528528
}

compiler/rustc_expand/src/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ impl<'a> ExtCtxt<'a> {
486486
self.pat(span, PatKind::Wild)
487487
}
488488
pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> {
489-
self.pat(span, PatKind::Lit(expr))
489+
self.pat(span, PatKind::Expr(expr))
490490
}
491491
pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
492492
self.pat_ident_binding_mode(span, ident, ast::BindingMode::NONE)

compiler/rustc_hir/src/hir.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ impl<'hir> Pat<'hir> {
13861386

13871387
use PatKind::*;
13881388
match self.kind {
1389-
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
1389+
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => true,
13901390
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_short_(it),
13911391
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
13921392
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
@@ -1413,7 +1413,7 @@ impl<'hir> Pat<'hir> {
14131413

14141414
use PatKind::*;
14151415
match self.kind {
1416-
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
1416+
Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Path(_) | Err(_) => {}
14171417
Box(s) | Deref(s) | Ref(s, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
14181418
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
14191419
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
@@ -1519,6 +1519,26 @@ impl fmt::Debug for DotDotPos {
15191519
}
15201520
}
15211521

1522+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
1523+
pub struct PatExpr<'hir> {
1524+
pub hir_id: HirId,
1525+
pub span: Span,
1526+
pub kind: PatExprKind<'hir>,
1527+
}
1528+
1529+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
1530+
pub enum PatExprKind<'hir> {
1531+
Lit {
1532+
lit: &'hir Lit,
1533+
// FIXME: move this into `Lit` and handle negated literal expressions
1534+
// once instead of matching on unop neg expressions everywhere.
1535+
negated: bool,
1536+
},
1537+
ConstBlock(ConstBlock),
1538+
/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
1539+
Path(QPath<'hir>),
1540+
}
1541+
15221542
#[derive(Debug, Clone, Copy, HashStable_Generic)]
15231543
pub enum PatKind<'hir> {
15241544
/// Represents a wildcard pattern (i.e., `_`).
@@ -1563,14 +1583,14 @@ pub enum PatKind<'hir> {
15631583
/// A reference pattern (e.g., `&mut (a, b)`).
15641584
Ref(&'hir Pat<'hir>, Mutability),
15651585

1566-
/// A literal.
1567-
Lit(&'hir Expr<'hir>),
1586+
/// A literal, const block or path.
1587+
Expr(&'hir PatExpr<'hir>),
15681588

15691589
/// A guard pattern (e.g., `x if guard(x)`).
15701590
Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),
15711591

15721592
/// A range pattern (e.g., `1..=2` or `1..2`).
1573-
Range(Option<&'hir Expr<'hir>>, Option<&'hir Expr<'hir>>, RangeEnd),
1593+
Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),
15741594

15751595
/// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
15761596
///
@@ -4144,6 +4164,10 @@ pub enum Node<'hir> {
41444164
OpaqueTy(&'hir OpaqueTy<'hir>),
41454165
Pat(&'hir Pat<'hir>),
41464166
PatField(&'hir PatField<'hir>),
4167+
/// Needed as its own node with its own HirId for tracking
4168+
/// the unadjusted type of literals within patterns
4169+
/// (e.g. byte str literals not being of slice type).
4170+
PatExpr(&'hir PatExpr<'hir>),
41474171
Arm(&'hir Arm<'hir>),
41484172
Block(&'hir Block<'hir>),
41494173
LetStmt(&'hir LetStmt<'hir>),
@@ -4200,6 +4224,7 @@ impl<'hir> Node<'hir> {
42004224
| Node::Block(..)
42014225
| Node::Ctor(..)
42024226
| Node::Pat(..)
4227+
| Node::PatExpr(..)
42034228
| Node::Arm(..)
42044229
| Node::LetStmt(..)
42054230
| Node::Crate(..)

compiler/rustc_hir/src/intravisit.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ pub trait Visitor<'v>: Sized {
342342
fn visit_pat_field(&mut self, f: &'v PatField<'v>) -> Self::Result {
343343
walk_pat_field(self, f)
344344
}
345+
fn visit_pat_expr(&mut self, expr: &'v PatExpr<'v>) -> Self::Result {
346+
walk_pat_expr(self, expr)
347+
}
345348
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
346349
walk_anon_const(self, c)
347350
}
@@ -685,10 +688,10 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
685688
try_visit!(visitor.visit_ident(ident));
686689
visit_opt!(visitor, visit_pat, optional_subpattern);
687690
}
688-
PatKind::Lit(ref expression) => try_visit!(visitor.visit_expr(expression)),
691+
PatKind::Expr(ref expression) => try_visit!(visitor.visit_pat_expr(expression)),
689692
PatKind::Range(ref lower_bound, ref upper_bound, _) => {
690-
visit_opt!(visitor, visit_expr, lower_bound);
691-
visit_opt!(visitor, visit_expr, upper_bound);
693+
visit_opt!(visitor, visit_pat_expr, lower_bound);
694+
visit_opt!(visitor, visit_pat_expr, upper_bound);
692695
}
693696
PatKind::Never | PatKind::Wild | PatKind::Err(_) => (),
694697
PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
@@ -710,6 +713,15 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
710713
visitor.visit_pat(field.pat)
711714
}
712715

716+
pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>) -> V::Result {
717+
try_visit!(visitor.visit_id(expr.hir_id));
718+
match &expr.kind {
719+
PatExprKind::Lit { .. } => V::Result::output(),
720+
PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
721+
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, expr.hir_id, expr.span),
722+
}
723+
}
724+
713725
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) -> V::Result {
714726
try_visit!(visitor.visit_id(constant.hir_id));
715727
visitor.visit_nested_body(constant.body)

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ fn resolve_local<'tcx>(
704704
| PatKind::Wild
705705
| PatKind::Never
706706
| PatKind::Path(_)
707-
| PatKind::Lit(_)
707+
| PatKind::Expr(_)
708708
| PatKind::Range(_, _, _)
709709
| PatKind::Err(_) => false,
710710
}

0 commit comments

Comments
 (0)