|
| 1 | +use std::sync::Arc; |
| 2 | + |
1 | 3 | use rustc_ast::ptr::P;
|
2 | 4 | use rustc_ast::*;
|
3 | 5 | use rustc_data_structures::stack::ensure_sufficient_stack;
|
4 | 6 | use rustc_hir as hir;
|
5 | 7 | 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}; |
7 | 10 | use rustc_span::{Ident, Span};
|
8 | 11 |
|
9 | 12 | use super::errors::{
|
@@ -35,8 +38,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
35 | 38 | lower_sub,
|
36 | 39 | );
|
37 | 40 | }
|
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)); |
40 | 43 | }
|
41 | 44 | PatKind::TupleStruct(qself, path, pats) => {
|
42 | 45 | let qpath = self.lower_qpath(
|
@@ -66,7 +69,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
66 | 69 | ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
67 | 70 | None,
|
68 | 71 | );
|
69 |
| - break hir::PatKind::Path(qpath); |
| 72 | + let kind = hir::PatExprKind::Path(qpath); |
| 73 | + let expr = hir::PatExpr { hir_id: pat_hir_id, span: pattern.span, kind }; |
| 74 | + let expr = self.arena.alloc(expr); |
| 75 | + return hir::Pat { |
| 76 | + hir_id: self.next_id(), |
| 77 | + kind: hir::PatKind::Expr(expr), |
| 78 | + span: pattern.span, |
| 79 | + default_binding_modes: true, |
| 80 | + }; |
70 | 81 | }
|
71 | 82 | PatKind::Struct(qself, path, fields, etc) => {
|
72 | 83 | let qpath = self.lower_qpath(
|
@@ -302,14 +313,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
302 | 313 | Some(res) => {
|
303 | 314 | let hir_id = self.next_id();
|
304 | 315 | let res = self.lower_res(res);
|
305 |
| - hir::PatKind::Path(hir::QPath::Resolved( |
| 316 | + let kind = hir::PatExprKind::Path(hir::QPath::Resolved( |
306 | 317 | None,
|
307 | 318 | self.arena.alloc(hir::Path {
|
308 | 319 | span: self.lower_span(ident.span),
|
309 | 320 | res,
|
310 | 321 | segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
|
311 | 322 | }),
|
312 |
| - )) |
| 323 | + )); |
| 324 | + let lit = hir::PatExpr { kind, hir_id: self.next_id(), span: ident.span }; |
| 325 | + let lit = self.arena.alloc(lit); |
| 326 | + hir::PatKind::Expr(lit) |
313 | 327 | }
|
314 | 328 | }
|
315 | 329 | }
|
@@ -366,24 +380,54 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
366 | 380 | // }
|
367 | 381 | // m!(S);
|
368 | 382 | // ```
|
369 |
| - fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir::Expr<'hir> { |
370 |
| - match &expr.kind { |
371 |
| - ExprKind::Lit(..) |
372 |
| - | ExprKind::ConstBlock(..) |
373 |
| - | ExprKind::IncludedBytes(..) |
374 |
| - | ExprKind::Err(_) |
375 |
| - | ExprKind::Dummy => {} |
376 |
| - ExprKind::Path(..) if allow_paths => {} |
377 |
| - ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} |
| 383 | + fn lower_expr_within_pat( |
| 384 | + &mut self, |
| 385 | + expr: &Expr, |
| 386 | + allow_paths: bool, |
| 387 | + ) -> &'hir hir::PatExpr<'hir> { |
| 388 | + let err = |guar| hir::PatExprKind::Lit { |
| 389 | + lit: self.arena.alloc(respan(self.lower_span(expr.span), LitKind::Err(guar))), |
| 390 | + negated: false, |
| 391 | + }; |
| 392 | + let kind = match &expr.kind { |
| 393 | + ExprKind::Lit(lit) => { |
| 394 | + hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: false } |
| 395 | + } |
| 396 | + ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)), |
| 397 | + ExprKind::IncludedBytes(bytes) => hir::PatExprKind::Lit { |
| 398 | + lit: self.arena.alloc(respan( |
| 399 | + self.lower_span(expr.span), |
| 400 | + LitKind::ByteStr(Arc::clone(bytes), StrStyle::Cooked), |
| 401 | + )), |
| 402 | + negated: false, |
| 403 | + }, |
| 404 | + ExprKind::Err(guar) => err(*guar), |
| 405 | + ExprKind::Dummy => span_bug!(expr.span, "lowered ExprKind::Dummy"), |
| 406 | + ExprKind::Path(qself, path) if allow_paths => hir::PatExprKind::Path(self.lower_qpath( |
| 407 | + expr.id, |
| 408 | + qself, |
| 409 | + path, |
| 410 | + ParamMode::Optional, |
| 411 | + AllowReturnTypeNotation::No, |
| 412 | + ImplTraitContext::Disallowed(ImplTraitPosition::Path), |
| 413 | + None, |
| 414 | + )), |
| 415 | + ExprKind::Unary(UnOp::Neg, inner) if let ExprKind::Lit(lit) = &inner.kind => { |
| 416 | + hir::PatExprKind::Lit { lit: self.lower_lit(lit, expr.span), negated: true } |
| 417 | + } |
378 | 418 | _ => {
|
379 | 419 | let pattern_from_macro = expr.is_approximately_pattern();
|
380 | 420 | let guar = self.dcx().emit_err(ArbitraryExpressionInPattern {
|
381 | 421 | span: expr.span,
|
382 | 422 | pattern_from_macro_note: pattern_from_macro,
|
383 | 423 | });
|
384 |
| - return self.arena.alloc(self.expr_err(expr.span, guar)); |
| 424 | + err(guar) |
385 | 425 | }
|
386 |
| - } |
387 |
| - self.lower_expr(expr) |
| 426 | + }; |
| 427 | + self.arena.alloc(hir::PatExpr { |
| 428 | + hir_id: self.lower_node_id(expr.id), |
| 429 | + span: expr.span, |
| 430 | + kind, |
| 431 | + }) |
388 | 432 | }
|
389 | 433 | }
|
0 commit comments