@@ -638,51 +638,54 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
638
638
let ty = self . typeck_results . node_type ( id) ;
639
639
let res = self . typeck_results . qpath_res ( qpath, id) ;
640
640
641
- let pat_from_kind = |kind| Box :: new ( Pat { span , ty , kind } ) ;
642
-
643
- let ( def_id , is_associated_const ) = match res {
644
- Res :: Def ( DefKind :: Const , def_id ) => ( def_id, false ) ,
645
- Res :: Def ( DefKind :: AssocConst , def_id ) => ( def_id , true ) ,
641
+ let ( def_id , user_ty ) = match res {
642
+ Res :: Def ( DefKind :: Const , def_id ) => ( def_id , None ) ,
643
+ Res :: Def ( DefKind :: AssocConst , def_id ) => {
644
+ ( def_id, self . typeck_results . user_provided_types ( ) . get ( id ) )
645
+ }
646
646
647
- _ => return pat_from_kind ( self . lower_variant_or_leaf ( res, id, span, ty, vec ! [ ] ) ) ,
647
+ _ => {
648
+ // The path isn't the name of a constant, so it must actually
649
+ // be a unit struct or unit variant (e.g. `Option::None`).
650
+ let kind = self . lower_variant_or_leaf ( res, id, span, ty, vec ! [ ] ) ;
651
+ return Box :: new ( Pat { span, ty, kind } ) ;
652
+ }
648
653
} ;
649
654
655
+ // Lower the named constant to a THIR pattern.
650
656
let args = self . typeck_results . node_args ( id) ;
651
657
let c = ty:: Const :: new_unevaluated ( self . tcx , ty:: UnevaluatedConst { def : def_id, args } ) ;
652
658
let subpattern = self . const_to_pat ( c, ty, id, span) ;
653
- let pattern = Box :: new ( Pat {
654
- span,
655
- ty,
656
- kind : PatKind :: ExpandedConstant { subpattern, def_id, is_inline : false } ,
657
- } ) ;
658
659
659
- if !is_associated_const {
660
- return pattern;
661
- }
660
+ // Wrap the pattern in a marker node to indicate that it is the result
661
+ // of lowering a named constant. This marker is used for improved
662
+ // diagnostics in some situations, but has no effect at runtime.
663
+ let mut pattern = {
664
+ let kind = PatKind :: ExpandedConstant { subpattern, def_id, is_inline : false } ;
665
+ Box :: new ( Pat { span, ty, kind } )
666
+ } ;
662
667
663
- let user_provided_types = self . typeck_results . user_provided_types ( ) ;
664
- if let Some ( & user_ty) = user_provided_types. get ( id) {
668
+ // If this is an associated constant with an explicit user-written
669
+ // type, add an ascription node (e.g. `<Foo<'a> as MyTrait>::CONST`).
670
+ if let Some ( & user_ty) = user_ty {
665
671
let annotation = CanonicalUserTypeAnnotation {
666
672
user_ty : Box :: new ( user_ty) ,
667
673
span,
668
674
inferred_ty : self . typeck_results . node_type ( id) ,
669
675
} ;
670
- Box :: new ( Pat {
671
- span,
672
- kind : PatKind :: AscribeUserType {
673
- subpattern : pattern,
674
- ascription : Ascription {
675
- annotation,
676
- // Note that use `Contravariant` here. See the
677
- // `variance` field documentation for details.
678
- variance : ty:: Contravariant ,
679
- } ,
676
+ let kind = PatKind :: AscribeUserType {
677
+ subpattern : pattern,
678
+ ascription : Ascription {
679
+ annotation,
680
+ // Note that we use `Contravariant` here. See the
681
+ // `variance` field documentation for details.
682
+ variance : ty:: Contravariant ,
680
683
} ,
681
- ty,
682
- } )
683
- } else {
684
- pattern
684
+ } ;
685
+ pattern = Box :: new ( Pat { span, kind, ty } ) ;
685
686
}
687
+
688
+ pattern
686
689
}
687
690
688
691
/// Converts inline const patterns.
0 commit comments