@@ -638,51 +638,54 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
638638 let ty = self . typeck_results . node_type ( id) ;
639639 let res = self . typeck_results . qpath_res ( qpath, id) ;
640640
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+ }
646646
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+ }
648653 } ;
649654
655+ // Lower the named constant to a THIR pattern.
650656 let args = self . typeck_results . node_args ( id) ;
651657 let c = ty:: Const :: new_unevaluated ( self . tcx , ty:: UnevaluatedConst { def : def_id, args } ) ;
652658 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- } ) ;
658659
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+ } ;
662667
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 {
665671 let annotation = CanonicalUserTypeAnnotation {
666672 user_ty : Box :: new ( user_ty) ,
667673 span,
668674 inferred_ty : self . typeck_results . node_type ( id) ,
669675 } ;
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 ,
680683 } ,
681- ty,
682- } )
683- } else {
684- pattern
684+ } ;
685+ pattern = Box :: new ( Pat { span, kind, ty } ) ;
685686 }
687+
688+ pattern
686689 }
687690
688691 /// Converts inline const patterns.
0 commit comments