@@ -678,8 +678,25 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
678
678
let mut let_suggestion = None ;
679
679
let mut misc_suggestion = None ;
680
680
let mut interpreted_as_const = None ;
681
+ let mut interpreted_as_const_sugg = None ;
681
682
682
- if let PatKind :: Constant { .. }
683
+ if let PatKind :: ExpandedConstant { def_id, is_inline : false , .. }
684
+ | PatKind :: AscribeUserType {
685
+ subpattern :
686
+ box Pat { kind : PatKind :: ExpandedConstant { def_id, is_inline : false , .. } , .. } ,
687
+ ..
688
+ } = pat. kind
689
+ && let DefKind :: Const = self . tcx . def_kind ( def_id)
690
+ && let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( pat. span )
691
+ // We filter out paths with multiple path::segments.
692
+ && snippet. chars ( ) . all ( |c| c. is_alphanumeric ( ) || c == '_' )
693
+ {
694
+ let span = self . tcx . def_span ( def_id) ;
695
+ let variable = self . tcx . item_name ( def_id) . to_string ( ) ;
696
+ // When we encounter a constant as the binding name, point at the `const` definition.
697
+ interpreted_as_const = Some ( span) ;
698
+ interpreted_as_const_sugg = Some ( InterpretedAsConst { span : pat. span , variable } ) ;
699
+ } else if let PatKind :: Constant { .. }
683
700
| PatKind :: AscribeUserType {
684
701
subpattern : box Pat { kind : PatKind :: Constant { .. } , .. } ,
685
702
..
@@ -692,9 +709,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
692
709
misc_suggestion = Some ( MiscPatternSuggestion :: AttemptedIntegerLiteral {
693
710
start_span : pat. span . shrink_to_lo ( ) ,
694
711
} ) ;
695
- } else if snippet. chars ( ) . all ( |c| c. is_alphanumeric ( ) || c == '_' ) {
696
- interpreted_as_const =
697
- Some ( InterpretedAsConst { span : pat. span , variable : snippet } ) ;
698
712
}
699
713
}
700
714
@@ -743,6 +757,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
743
757
uncovered : Uncovered :: new ( pat. span , & cx, witnesses) ,
744
758
inform,
745
759
interpreted_as_const,
760
+ interpreted_as_const_sugg,
746
761
witness_1_is_privately_uninhabited,
747
762
_p : ( ) ,
748
763
pattern_ty,
@@ -1112,13 +1127,13 @@ fn report_non_exhaustive_match<'p, 'tcx>(
1112
1127
if ty. is_ptr_sized_integral ( ) {
1113
1128
if ty. inner ( ) == cx. tcx . types . usize {
1114
1129
err. note ( format ! (
1115
- "`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
1116
- exhaustively",
1130
+ "`{ty}` does not have a fixed maximum value, so half-open ranges are \
1131
+ necessary to match exhaustively",
1117
1132
) ) ;
1118
1133
} else if ty. inner ( ) == cx. tcx . types . isize {
1119
1134
err. note ( format ! (
1120
- "`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
1121
- exhaustively",
1135
+ "`{ty}` does not have fixed minimum and maximum values, so half-open \
1136
+ ranges are necessary to match exhaustively",
1122
1137
) ) ;
1123
1138
}
1124
1139
} else if ty. inner ( ) == cx. tcx . types . str_ {
@@ -1139,6 +1154,31 @@ fn report_non_exhaustive_match<'p, 'tcx>(
1139
1154
}
1140
1155
}
1141
1156
1157
+ for & arm in arms {
1158
+ let arm = & thir. arms [ arm] ;
1159
+ if let PatKind :: ExpandedConstant { def_id, is_inline : false , .. } = arm. pattern . kind
1160
+ && let Ok ( snippet) = cx. tcx . sess . source_map ( ) . span_to_snippet ( arm. pattern . span )
1161
+ // We filter out paths with multiple path::segments.
1162
+ && snippet. chars ( ) . all ( |c| c. is_alphanumeric ( ) || c == '_' )
1163
+ {
1164
+ let const_name = cx. tcx . item_name ( def_id) ;
1165
+ err. span_label (
1166
+ arm. pattern . span ,
1167
+ format ! (
1168
+ "this pattern doesn't introduce a new catch-all binding, but rather pattern \
1169
+ matches against the value of constant `{const_name}`",
1170
+ ) ,
1171
+ ) ;
1172
+ err. span_note ( cx. tcx . def_span ( def_id) , format ! ( "constant `{const_name}` defined here" ) ) ;
1173
+ err. span_suggestion_verbose (
1174
+ arm. pattern . span . shrink_to_hi ( ) ,
1175
+ "if you meant to introduce a binding, use a different name" ,
1176
+ "_var" . to_string ( ) ,
1177
+ Applicability :: MaybeIncorrect ,
1178
+ ) ;
1179
+ }
1180
+ }
1181
+
1142
1182
// Whether we suggest the actual missing patterns or `_`.
1143
1183
let suggest_the_witnesses = witnesses. len ( ) < 4 ;
1144
1184
let suggested_arm = if suggest_the_witnesses {
0 commit comments