@@ -3,11 +3,11 @@ use std::sync::Arc;
33use rustc_ast:: ptr:: P ;
44use rustc_ast:: * ;
55use 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 } ;
88use rustc_middle:: span_bug;
99use rustc_span:: source_map:: { Spanned , respan} ;
10- use rustc_span:: { Ident , Span } ;
10+ use rustc_span:: { DesugaringKind , Ident , Span , kw } ;
1111
1212use super :: errors:: {
1313 ArbitraryExpressionInPattern , ExtraDoubleDot , MisplacedDoubleDot , SubTupleBinding ,
@@ -430,22 +430,119 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
430430 self . arena . alloc ( hir:: PatExpr { hir_id : self . lower_node_id ( expr. id ) , span, kind } )
431431 }
432432
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) )
435439 }
436440
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 > {
438442 // loop here to avoid recursion
439443 let pat_hir_id = self . lower_node_id ( pattern. id ) ;
440444 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+ } ) ,
445465 ) ,
446466 TyPatKind :: Err ( guar) => hir:: TyPatKind :: Err ( * guar) ,
447467 } ;
448468
449469 hir:: TyPat { hir_id : pat_hir_id, kind : node, span : self . lower_span ( pattern. span ) }
450470 }
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+ }
451548}
0 commit comments