Skip to content

Commit dbdec20

Browse files
committed
Auto merge of rust-lang#134248 - oli-obk:patkind-path-removal, r=<try>
Merge `PatKind::Path` into `PatKind::Lit` Follow-up to rust-lang#134228 We always had a duplication where `Path`s could be represented as `PatKind::Path` or `PatKind::Lit(ExprKind::Path)`. We had to handle both everywhere, and still do after rust-lang#134228, so I'm removing it now.
2 parents 73c0ae6 + 9d7525b commit dbdec20

File tree

29 files changed

+210
-179
lines changed

29 files changed

+210
-179
lines changed

Diff for: compiler/rustc_ast_lowering/src/index.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
213213
self.insert(expr.span, expr.hir_id, Node::PatExpr(expr));
214214

215215
self.with_parent(expr.hir_id, |this| {
216-
intravisit::walk_pat_expr(this, expr);
216+
intravisit::walk_pat_expr(this, expr.hir_id, expr.span, &expr.kind);
217217
});
218218
}
219219

Diff for: compiler/rustc_ast_lowering/src/pat.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
117117
break hir::PatKind::Ref(self.lower_pat(inner), *mutbl);
118118
}
119119
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
120+
let mut lower_end = |e: &Expr| {
121+
&*self.arena.alloc(hir::PatExpr {
122+
hir_id: self.lower_node_id(e.id),
123+
span: e.span,
124+
kind: self.lower_expr_within_pat(e, true),
125+
})
126+
};
120127
break hir::PatKind::Range(
121-
e1.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
122-
e2.as_deref().map(|e| self.lower_expr_within_pat(e, true)),
128+
e1.as_deref().map(|e| lower_end(e)),
129+
e2.as_deref().map(|e| lower_end(e)),
123130
self.lower_range_end(end, e2.is_some()),
124131
);
125132
}
@@ -370,16 +377,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
370377
// }
371378
// m!(S);
372379
// ```
373-
fn lower_expr_within_pat(
374-
&mut self,
375-
expr: &Expr,
376-
allow_paths: bool,
377-
) -> &'hir hir::PatExpr<'hir> {
380+
fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> hir::PatExprKind<'hir> {
378381
let err = |guar| hir::PatExprKind::Lit {
379382
lit: self.arena.alloc(respan(self.lower_span(expr.span), LitKind::Err(guar))),
380383
negated: false,
381384
};
382-
let kind = match &expr.kind {
385+
match &expr.kind {
383386
ExprKind::Lit(lit) => {
384387
hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: false }
385388
}
@@ -413,11 +416,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
413416
});
414417
err(guar)
415418
}
416-
};
417-
self.arena.alloc(hir::PatExpr {
418-
hir_id: self.lower_node_id(expr.id),
419-
span: expr.span,
420-
kind,
421-
})
419+
}
422420
}
423421
}

Diff for: compiler/rustc_hir/src/hir.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,7 @@ impl fmt::Debug for DotDotPos {
15211521

15221522
#[derive(Debug, Clone, Copy, HashStable_Generic)]
15231523
pub struct PatExpr<'hir> {
1524+
#[stable_hasher(ignore)]
15241525
pub hir_id: HirId,
15251526
pub span: Span,
15261527
pub kind: PatExprKind<'hir>,
@@ -1584,7 +1585,7 @@ pub enum PatKind<'hir> {
15841585
Ref(&'hir Pat<'hir>, Mutability),
15851586

15861587
/// A literal, const block or path.
1587-
Expr(&'hir PatExpr<'hir>),
1588+
Expr(PatExprKind<'hir>),
15881589

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

Diff for: compiler/rustc_hir/src/intravisit.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ pub trait Visitor<'v>: Sized {
343343
walk_pat_field(self, f)
344344
}
345345
fn visit_pat_expr(&mut self, expr: &'v PatExpr<'v>) -> Self::Result {
346-
walk_pat_expr(self, expr)
346+
walk_pat_expr(self, expr.hir_id, expr.span, &expr.kind)
347347
}
348348
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
349349
walk_anon_const(self, c)
@@ -688,7 +688,9 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V:
688688
try_visit!(visitor.visit_ident(ident));
689689
visit_opt!(visitor, visit_pat, optional_subpattern);
690690
}
691-
PatKind::Expr(ref expression) => try_visit!(visitor.visit_pat_expr(expression)),
691+
PatKind::Expr(ref expression) => {
692+
try_visit!(walk_pat_expr(visitor, pattern.hir_id, pattern.span, expression))
693+
}
692694
PatKind::Range(ref lower_bound, ref upper_bound, _) => {
693695
visit_opt!(visitor, visit_pat_expr, lower_bound);
694696
visit_opt!(visitor, visit_pat_expr, upper_bound);
@@ -713,12 +715,17 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
713715
visitor.visit_pat(field.pat)
714716
}
715717

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 {
718+
pub fn walk_pat_expr<'v, V: Visitor<'v>>(
719+
visitor: &mut V,
720+
hir_id: HirId,
721+
span: Span,
722+
kind: &'v PatExprKind<'v>,
723+
) -> V::Result {
724+
try_visit!(visitor.visit_id(hir_id));
725+
match kind {
719726
PatExprKind::Lit { .. } => V::Result::output(),
720727
PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
721-
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, expr.hir_id, expr.span),
728+
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, hir_id, span),
722729
}
723730
}
724731

Diff for: compiler/rustc_hir_pretty/src/lib.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ impl<'a> State<'a> {
199199
Node::OpaqueTy(o) => self.print_opaque_ty(o),
200200
Node::Pat(a) => self.print_pat(a),
201201
Node::PatField(a) => self.print_patfield(a),
202-
Node::PatExpr(a) => self.print_pat_expr(a),
202+
Node::PatExpr(a) => self.print_pat_expr(&a.kind),
203203
Node::Arm(a) => self.print_arm(a),
204204
Node::Infer(_) => self.word("_"),
205205
Node::PreciseCapturingNonLifetimeArg(param) => self.print_ident(param.ident),
@@ -1850,8 +1850,8 @@ impl<'a> State<'a> {
18501850
}
18511851
}
18521852

1853-
fn print_pat_expr(&mut self, expr: &hir::PatExpr<'_>) {
1854-
match &expr.kind {
1853+
fn print_pat_expr(&mut self, kind: &hir::PatExprKind<'_>) {
1854+
match kind {
18551855
hir::PatExprKind::Lit { lit, negated } => {
18561856
if *negated {
18571857
self.word("-");
@@ -1980,17 +1980,17 @@ impl<'a> State<'a> {
19801980
self.pclose();
19811981
}
19821982
}
1983-
PatKind::Expr(e) => self.print_pat_expr(e),
1983+
PatKind::Expr(ref e) => self.print_pat_expr(e),
19841984
PatKind::Range(begin, end, end_kind) => {
19851985
if let Some(expr) = begin {
1986-
self.print_pat_expr(expr);
1986+
self.print_pat_expr(&expr.kind);
19871987
}
19881988
match end_kind {
19891989
RangeEnd::Included => self.word("..."),
19901990
RangeEnd::Excluded => self.word(".."),
19911991
}
19921992
if let Some(expr) = end {
1993-
self.print_pat_expr(expr);
1993+
self.print_pat_expr(&expr.kind);
19941994
}
19951995
}
19961996
PatKind::Slice(before, slice, after) => {

Diff for: compiler/rustc_hir_typeck/src/pat.rs

+43-30
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
256256
}
257257
_ => None,
258258
};
259-
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
259+
let (adjust_mode, opt_expr_ty) = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
260260
let (expected, binding_mode, max_ref_mutbl) =
261261
self.calc_default_binding_mode(pat, expected, binding_mode, adjust_mode, max_ref_mutbl);
262262
let pat_info = PatInfo {
@@ -271,7 +271,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
271271
PatKind::Wild | PatKind::Err(_) => expected,
272272
// We allow any type here; we ensure that the type is uninhabited during match checking.
273273
PatKind::Never => expected,
274-
PatKind::Expr(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
274+
PatKind::Expr(ref lt) => {
275+
self.check_pat_lit(pat.hir_id, pat.span, lt, expected, ti, opt_expr_ty.unwrap())
276+
}
275277
PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
276278
PatKind::Binding(ba, var_id, ident, sub) => {
277279
self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info)
@@ -376,13 +378,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
376378
/// How should the binding mode and expected type be adjusted?
377379
///
378380
/// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
379-
fn calc_adjust_mode(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> AdjustMode {
381+
///
382+
/// Returns the unadjusted type for expr patterns.
383+
fn calc_adjust_mode(
384+
&self,
385+
pat: &'tcx Pat<'tcx>,
386+
opt_path_res: Option<Res>,
387+
) -> (AdjustMode, Option<Ty<'tcx>>) {
380388
// When we perform destructuring assignment, we disable default match bindings, which are
381389
// unintuitive in this context.
382390
if !pat.default_binding_modes {
383-
return AdjustMode::Reset;
391+
return (AdjustMode::Reset, None);
384392
}
385-
match &pat.kind {
393+
let adjust = match &pat.kind {
386394
// Type checking these product-like types successfully always require
387395
// that the expected type be of those types and not reference types.
388396
PatKind::Struct(..)
@@ -399,9 +407,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
399407
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
400408
//
401409
// Call `resolve_vars_if_possible` here for inline const blocks.
402-
PatKind::Expr(lt) => match self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt)).kind() {
403-
ty::Ref(..) => AdjustMode::Pass,
404-
_ => AdjustMode::Peel,
410+
PatKind::Expr(lt) => {
411+
let ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt, pat.hir_id, pat.span));
412+
let adjust = match ty.kind() {
413+
ty::Ref(..) => AdjustMode::Pass,
414+
_ => AdjustMode::Peel,
415+
};
416+
return (adjust, Some(ty))
405417
},
406418
PatKind::Path(_) => match opt_path_res.unwrap() {
407419
// These constants can be of a reference type, e.g. `const X: &u8 = &0;`.
@@ -431,7 +443,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
431443
| PatKind::Or(_)
432444
// Like or-patterns, guard patterns just propogate to their subpatterns.
433445
| PatKind::Guard(..) => AdjustMode::Pass,
434-
}
446+
};
447+
(adjust, None)
435448
}
436449

437450
/// Peel off as many immediately nested `& mut?` from the expected type as possible
@@ -494,8 +507,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
494507
(expected, def_br, max_ref_mutbl)
495508
}
496509

497-
fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
498-
let ty = match &lt.kind {
510+
fn check_pat_expr_unadjusted(
511+
&self,
512+
kind: &'tcx hir::PatExprKind<'tcx>,
513+
hir_id: HirId,
514+
span: Span,
515+
) -> Ty<'tcx> {
516+
match kind {
499517
rustc_hir::PatExprKind::Lit { lit, .. } => {
500518
self.check_expr_lit(lit, Expectation::NoExpectation)
501519
}
@@ -504,42 +522,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
504522
}
505523
rustc_hir::PatExprKind::Path(qpath) => {
506524
let (res, opt_ty, segments) =
507-
self.resolve_ty_and_res_fully_qualified_call(qpath, lt.hir_id, lt.span);
508-
self.instantiate_value_path(segments, opt_ty, res, lt.span, lt.span, lt.hir_id).0
525+
self.resolve_ty_and_res_fully_qualified_call(qpath, hir_id, span);
526+
self.instantiate_value_path(segments, opt_ty, res, span, span, hir_id).0
509527
}
510-
};
511-
self.write_ty(lt.hir_id, ty);
512-
ty
528+
}
513529
}
514530

515531
fn check_pat_lit(
516532
&self,
533+
hir_id: HirId,
517534
span: Span,
518-
lt: &hir::PatExpr<'tcx>,
535+
lt: &hir::PatExprKind<'tcx>,
519536
expected: Ty<'tcx>,
520537
ti: &TopInfo<'tcx>,
538+
mut pat_ty: Ty<'tcx>,
521539
) -> Ty<'tcx> {
522-
// We've already computed the type above (when checking for a non-ref pat),
523-
// so avoid computing it again.
524-
let ty = self.node_ty(lt.hir_id);
525-
526540
// Byte string patterns behave the same way as array patterns
527541
// They can denote both statically and dynamically-sized byte arrays.
528-
let mut pat_ty = ty;
529542
if let hir::PatExprKind::Lit {
530543
lit: Spanned { node: ast::LitKind::ByteStr(..), .. }, ..
531-
} = lt.kind
544+
} = lt
532545
{
533546
let expected = self.structurally_resolve_type(span, expected);
534547
if let ty::Ref(_, inner_ty, _) = *expected.kind()
535548
&& self.try_structurally_resolve_type(span, inner_ty).is_slice()
536549
{
537550
let tcx = self.tcx;
538-
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
539-
self.typeck_results
540-
.borrow_mut()
541-
.treat_byte_string_as_slice
542-
.insert(lt.hir_id.local_id);
551+
trace!(?hir_id.local_id, "polymorphic byte string lit");
552+
self.typeck_results.borrow_mut().lit_pat_type_adjusted.insert(hir_id.local_id);
543553
pat_ty =
544554
Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, Ty::new_slice(tcx, tcx.types.u8));
545555
}
@@ -548,10 +558,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
548558
if self.tcx.features().string_deref_patterns()
549559
&& let hir::PatExprKind::Lit {
550560
lit: Spanned { node: ast::LitKind::Str(..), .. }, ..
551-
} = lt.kind
561+
} = lt
552562
{
553563
let tcx = self.tcx;
554564
let expected = self.resolve_vars_if_possible(expected);
565+
self.typeck_results.borrow_mut().lit_pat_type_adjusted.insert(hir_id.local_id);
555566
pat_ty = match expected.kind() {
556567
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => expected,
557568
ty::Str => Ty::new_static_str(tcx),
@@ -597,7 +608,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
597608
let calc_side = |opt_expr: Option<&'tcx hir::PatExpr<'tcx>>| match opt_expr {
598609
None => None,
599610
Some(expr) => {
600-
let ty = self.check_pat_expr_unadjusted(expr);
611+
let ty = self.check_pat_expr_unadjusted(&expr.kind, expr.hir_id, expr.span);
612+
613+
self.write_ty(expr.hir_id, ty);
601614
// Check that the end-point is possibly of numeric or char type.
602615
// The early check here is not for correctness, but rather better
603616
// diagnostics (e.g. when `&str` is being matched, `expected` will

Diff for: compiler/rustc_hir_typeck/src/writeback.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7979
debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
8080
wbcx.typeck_results.used_trait_imports = used_trait_imports;
8181

82-
wbcx.typeck_results.treat_byte_string_as_slice =
83-
mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);
82+
wbcx.typeck_results.lit_pat_type_adjusted =
83+
mem::take(&mut self.typeck_results.borrow_mut().lit_pat_type_adjusted);
8484

8585
debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);
8686

@@ -328,6 +328,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
328328
self.visit_field_id(field.hir_id);
329329
}
330330
}
331+
hir::PatKind::Expr(hir::PatExprKind::ConstBlock(ref c)) => {
332+
self.visit_const_block(p.span, c);
333+
}
331334
_ => {}
332335
};
333336

@@ -344,7 +347,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
344347
if let hir::PatExprKind::ConstBlock(c) = &expr.kind {
345348
self.visit_const_block(expr.span, c);
346349
}
347-
intravisit::walk_pat_expr(self, expr);
350+
intravisit::walk_pat_expr(self, expr.hir_id, expr.span, &expr.kind);
348351
}
349352

350353
fn visit_local(&mut self, l: &'tcx hir::LetStmt<'tcx>) {

Diff for: compiler/rustc_middle/src/ty/typeck_results.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,13 @@ pub struct TypeckResults<'tcx> {
199199
/// formatting modified file tests/ui/coroutine/retain-resume-ref.rs
200200
pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
201201

202-
/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
203-
/// as `&[u8]`, depending on the pattern in which they are used.
202+
/// We sometimes treat
203+
/// * byte string literals (which are of type `&[u8; N]`)
204+
/// as `&[u8]`, depending on the pattern in which they are used.
205+
/// * string literals (which are of type `&str`) as `String`
204206
/// This hashset records all instances where we behave
205207
/// like this to allow `const_to_pat` to reliably handle this situation.
206-
pub treat_byte_string_as_slice: ItemLocalSet,
208+
pub lit_pat_type_adjusted: ItemLocalSet,
207209

208210
/// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
209211
/// on closure size.
@@ -239,7 +241,7 @@ impl<'tcx> TypeckResults<'tcx> {
239241
closure_fake_reads: Default::default(),
240242
rvalue_scopes: Default::default(),
241243
coroutine_stalled_predicates: Default::default(),
242-
treat_byte_string_as_slice: Default::default(),
244+
lit_pat_type_adjusted: Default::default(),
243245
closure_size_eval: Default::default(),
244246
offset_of_data: Default::default(),
245247
}

Diff for: compiler/rustc_mir_build/src/thir/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub(crate) fn lit_to_const<'tcx>(
3333
};
3434

3535
let valtree = match (lit, ty.kind()) {
36-
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
36+
(ast::LitKind::Str(s, _), _) => {
3737
let str_bytes = s.as_str().as_bytes();
3838
ty::ValTree::from_raw_bytes(tcx, str_bytes)
3939
}

0 commit comments

Comments
 (0)