|
| 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