@@ -3,11 +3,11 @@ use std::sync::Arc;
3
3
use rustc_ast:: ptr:: P ;
4
4
use rustc_ast:: * ;
5
5
use rustc_data_structures:: stack:: ensure_sufficient_stack;
6
- use rustc_hir as hir ;
7
- use rustc_hir:: def :: Res ;
6
+ use rustc_hir:: def :: { DefKind , Res } ;
7
+ use rustc_hir:: { self as hir , LangItem } ;
8
8
use rustc_middle:: span_bug;
9
9
use rustc_span:: source_map:: { Spanned , respan} ;
10
- use rustc_span:: { Ident , Span } ;
10
+ use rustc_span:: { DesugaringKind , Ident , Span , kw } ;
11
11
12
12
use super :: errors:: {
13
13
ArbitraryExpressionInPattern , ExtraDoubleDot , MisplacedDoubleDot , SubTupleBinding ,
@@ -430,22 +430,119 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
430
430
self . arena . alloc ( hir:: PatExpr { hir_id : self . lower_node_id ( expr. id ) , span, kind } )
431
431
}
432
432
433
- pub ( crate ) fn lower_ty_pat ( & mut self , pattern : & TyPat ) -> & ' hir hir:: TyPat < ' hir > {
434
- self . arena . alloc ( self . lower_ty_pat_mut ( pattern) )
433
+ pub ( crate ) fn lower_ty_pat (
434
+ & mut self ,
435
+ pattern : & TyPat ,
436
+ base_type : Span ,
437
+ ) -> & ' hir hir:: TyPat < ' hir > {
438
+ self . arena . alloc ( self . lower_ty_pat_mut ( pattern, base_type) )
435
439
}
436
440
437
- fn lower_ty_pat_mut ( & mut self , pattern : & TyPat ) -> hir:: TyPat < ' hir > {
441
+ fn lower_ty_pat_mut ( & mut self , pattern : & TyPat , base_type : Span ) -> hir:: TyPat < ' hir > {
438
442
// loop here to avoid recursion
439
443
let pat_hir_id = self . lower_node_id ( pattern. id ) ;
440
444
let node = match & pattern. kind {
441
- TyPatKind :: Range ( e1, e2, Spanned { node : end, .. } ) => hir:: TyPatKind :: Range (
442
- e1. as_deref ( ) . map ( |e| self . lower_anon_const_to_const_arg ( e) ) ,
443
- e2. as_deref ( ) . map ( |e| self . lower_anon_const_to_const_arg ( e) ) ,
444
- self . lower_range_end ( end, e2. is_some ( ) ) ,
445
+ TyPatKind :: Range ( e1, e2, Spanned { node : end, span } ) => hir:: TyPatKind :: Range (
446
+ e1. as_deref ( ) . map ( |e| self . lower_anon_const_to_const_arg ( e) ) . unwrap_or_else ( || {
447
+ self . lower_ty_pat_range_end (
448
+ hir:: LangItem :: RangeMin ,
449
+ span. shrink_to_lo ( ) ,
450
+ base_type,
451
+ )
452
+ } ) ,
453
+ e2. as_deref ( )
454
+ . map ( |e| match end {
455
+ RangeEnd :: Included ( ..) => self . lower_anon_const_to_const_arg ( e) ,
456
+ RangeEnd :: Excluded => self . lower_excluded_range_end ( e) ,
457
+ } )
458
+ . unwrap_or_else ( || {
459
+ self . lower_ty_pat_range_end (
460
+ hir:: LangItem :: RangeMax ,
461
+ span. shrink_to_hi ( ) ,
462
+ base_type,
463
+ )
464
+ } ) ,
445
465
) ,
446
466
TyPatKind :: Err ( guar) => hir:: TyPatKind :: Err ( * guar) ,
447
467
} ;
448
468
449
469
hir:: TyPat { hir_id : pat_hir_id, kind : node, span : self . lower_span ( pattern. span ) }
450
470
}
471
+
472
+ fn lower_excluded_range_end ( & mut self , e : & AnonConst ) -> & ' hir hir:: ConstArg < ' hir > {
473
+ let span = self . lower_span ( e. value . span ) ;
474
+ let unstable_span = self . mark_span_with_reason (
475
+ DesugaringKind :: PatTyRange ,
476
+ span,
477
+ Some ( Arc :: clone ( & self . allow_pattern_type ) ) ,
478
+ ) ;
479
+ let anon_const = self . with_new_scopes ( span, |this| {
480
+ let def_id = this. local_def_id ( e. id ) ;
481
+ let hir_id = this. lower_node_id ( e. id ) ;
482
+ let body = this. lower_body ( |this| {
483
+ // Need to use a custom function as we can't just subtract `1` from a `char`.
484
+ let kind = hir:: ExprKind :: Path ( this. make_lang_item_qpath (
485
+ hir:: LangItem :: RangeSub ,
486
+ unstable_span,
487
+ None ,
488
+ ) ) ;
489
+ let fn_def = this. arena . alloc ( hir:: Expr { hir_id : this. next_id ( ) , kind, span } ) ;
490
+ let args = this. arena . alloc ( [ this. lower_expr_mut ( & e. value ) ] ) ;
491
+ (
492
+ & [ ] ,
493
+ hir:: Expr {
494
+ hir_id : this. next_id ( ) ,
495
+ kind : hir:: ExprKind :: Call ( fn_def, args) ,
496
+ span,
497
+ } ,
498
+ )
499
+ } ) ;
500
+ hir:: AnonConst { def_id, hir_id, body, span }
501
+ } ) ;
502
+ self . arena . alloc ( hir:: ConstArg {
503
+ hir_id : self . next_id ( ) ,
504
+ kind : hir:: ConstArgKind :: Anon ( self . arena . alloc ( anon_const) ) ,
505
+ } )
506
+ }
507
+
508
+ fn lower_ty_pat_range_end (
509
+ & mut self ,
510
+ lang_item : LangItem ,
511
+ span : Span ,
512
+ base_type : Span ,
513
+ ) -> & ' hir hir:: ConstArg < ' hir > {
514
+ let parent_def_id = self . current_hir_id_owner . def_id ;
515
+ let node_id = self . next_node_id ( ) ;
516
+
517
+ // Add a definition for the in-band const def.
518
+ // We're lowering a const argument that was originally thought to be a type argument,
519
+ // so the def collector didn't create the def ahead of time. That's why we have to do
520
+ // it here.
521
+ let def_id = self . create_def ( parent_def_id, node_id, kw:: Empty , DefKind :: AnonConst , span) ;
522
+ let hir_id = self . lower_node_id ( node_id) ;
523
+
524
+ let unstable_span = self . mark_span_with_reason (
525
+ DesugaringKind :: PatTyRange ,
526
+ self . lower_span ( span) ,
527
+ Some ( Arc :: clone ( & self . allow_pattern_type ) ) ,
528
+ ) ;
529
+ let span = self . lower_span ( base_type) ;
530
+
531
+ let path_expr = hir:: Expr {
532
+ hir_id : self . next_id ( ) ,
533
+ kind : hir:: ExprKind :: Path ( self . make_lang_item_qpath ( lang_item, unstable_span, None ) ) ,
534
+ span,
535
+ } ;
536
+
537
+ let ct = self . with_new_scopes ( span, |this| {
538
+ self . arena . alloc ( hir:: AnonConst {
539
+ def_id,
540
+ hir_id,
541
+ body : this. lower_body ( |_this| ( & [ ] , path_expr) ) ,
542
+ span,
543
+ } )
544
+ } ) ;
545
+ let hir_id = self . next_id ( ) ;
546
+ self . arena . alloc ( hir:: ConstArg { kind : hir:: ConstArgKind :: Anon ( ct) , hir_id } )
547
+ }
451
548
}
0 commit comments