@@ -153,19 +153,14 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
153
153
visit:: walk_expr ( cx, ex) ;
154
154
match ex. node {
155
155
ast:: ExprMatch ( ref scrut, ref arms, source) => {
156
- // First, check legality of move bindings.
157
156
for arm in arms. iter ( ) {
157
+ // First, check legality of move bindings.
158
158
check_legality_of_move_bindings ( cx,
159
159
arm. guard . is_some ( ) ,
160
160
arm. pats . as_slice ( ) ) ;
161
- for pat in arm. pats . iter ( ) {
162
- check_legality_of_bindings_in_at_patterns ( cx, & * * pat) ;
163
- }
164
- }
165
161
166
- // Second, if there is a guard on each arm, make sure it isn't
167
- // assigning or borrowing anything mutably.
168
- for arm in arms. iter ( ) {
162
+ // Second, if there is a guard on each arm, make sure it isn't
163
+ // assigning or borrowing anything mutably.
169
164
match arm. guard {
170
165
Some ( ref guard) => check_for_mutation_in_guard ( cx, & * * guard) ,
171
166
None => { }
@@ -179,13 +174,23 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
179
174
} ) . collect ( ) , arm. guard . as_ref ( ) . map ( |e| & * * e) )
180
175
} ) . collect :: < Vec < ( Vec < P < Pat > > , Option < & ast:: Expr > ) > > ( ) ;
181
176
177
+ // Bail out early if inlining failed.
182
178
if static_inliner. failed {
183
179
return ;
184
180
}
185
181
186
- // Third, check if there are any references to NaN that we should warn about.
187
- for & ( ref pats, _) in inlined_arms. iter ( ) {
188
- check_for_static_nan ( cx, pats. as_slice ( ) ) ;
182
+ for pat in inlined_arms
183
+ . iter ( )
184
+ . flat_map ( |& ( ref pats, _) | pats. iter ( ) ) {
185
+ // Third, check legality of move bindings.
186
+ check_legality_of_bindings_in_at_patterns ( cx, & * * pat) ;
187
+
188
+ // Fourth, check if there are any references to NaN that we should warn about.
189
+ check_for_static_nan ( cx, & * * pat) ;
190
+
191
+ // Fifth, check if for any of the patterns that match an enumerated type
192
+ // are bindings with the same name as one of the variants of said type.
193
+ check_for_bindings_named_the_same_as_variants ( cx, & * * pat) ;
189
194
}
190
195
191
196
// Fourth, check for unreachable arms.
@@ -239,21 +244,49 @@ fn is_expr_const_nan(tcx: &ty::ctxt, expr: &ast::Expr) -> bool {
239
244
}
240
245
}
241
246
242
- // Check that we do not match against a static NaN (#6804)
243
- fn check_for_static_nan ( cx : & MatchCheckCtxt , pats : & [ P < Pat > ] ) {
244
- for pat in pats. iter ( ) {
245
- walk_pat ( & * * pat, |p| {
246
- match p. node {
247
- ast:: PatLit ( ref expr) if is_expr_const_nan ( cx. tcx , & * * expr) => {
248
- span_warn ! ( cx. tcx. sess, p. span, E0003 ,
249
- "unmatchable NaN in pattern, \
250
- use the is_nan method in a guard instead") ;
247
+ fn check_for_bindings_named_the_same_as_variants ( cx : & MatchCheckCtxt , pat : & Pat ) {
248
+ walk_pat ( pat, |p| {
249
+ match p. node {
250
+ ast:: PatIdent ( ast:: BindByValue ( ast:: MutImmutable ) , ident, None ) => {
251
+ let pat_ty = ty:: pat_ty ( cx. tcx , p) ;
252
+ if let ty:: ty_enum( def_id, _) = pat_ty. sty {
253
+ let def = cx. tcx . def_map . borrow ( ) . get ( & p. id ) . cloned ( ) ;
254
+ if let Some ( DefLocal ( _) ) = def {
255
+ if ty:: enum_variants ( cx. tcx , def_id) . iter ( ) . any ( |variant|
256
+ token:: get_name ( variant. name ) == token:: get_name ( ident. node . name )
257
+ && variant. args . len ( ) == 0
258
+ ) {
259
+ span_warn ! ( cx. tcx. sess, p. span, E0170 ,
260
+ "pattern binding `{}` is named the same as one \
261
+ of the variants of the type `{}`",
262
+ token:: get_ident( ident. node) . get( ) , ty_to_string( cx. tcx, pat_ty) ) ;
263
+ span_help ! ( cx. tcx. sess, p. span,
264
+ "if you meant to match on a variant, \
265
+ consider making the path in the pattern qualified: `{}::{}`",
266
+ ty_to_string( cx. tcx, pat_ty) , token:: get_ident( ident. node) . get( ) ) ;
267
+ }
268
+ }
251
269
}
252
- _ => ( )
253
270
}
254
- true
255
- } ) ;
256
- }
271
+ _ => ( )
272
+ }
273
+ true
274
+ } ) ;
275
+ }
276
+
277
+ // Check that we do not match against a static NaN (#6804)
278
+ fn check_for_static_nan ( cx : & MatchCheckCtxt , pat : & Pat ) {
279
+ walk_pat ( pat, |p| {
280
+ match p. node {
281
+ ast:: PatLit ( ref expr) if is_expr_const_nan ( cx. tcx , & * * expr) => {
282
+ span_warn ! ( cx. tcx. sess, p. span, E0003 ,
283
+ "unmatchable NaN in pattern, \
284
+ use the is_nan method in a guard instead") ;
285
+ }
286
+ _ => ( )
287
+ }
288
+ true
289
+ } ) ;
257
290
}
258
291
259
292
// Check for unreachable patterns
@@ -414,8 +447,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
414
447
& Variant ( vid) =>
415
448
( vid, ty:: enum_variant_with_id ( cx. tcx , cid, vid) . arg_names . is_some ( ) ) ,
416
449
_ =>
417
- ( cid, ty:: lookup_struct_fields ( cx. tcx , cid) . iter ( )
418
- . any ( |field| field. name != token:: special_idents:: unnamed_field. name ) )
450
+ ( cid, !ty:: is_tuple_struct ( cx. tcx , cid) )
419
451
} ;
420
452
if is_structure {
421
453
let fields = ty:: lookup_struct_fields ( cx. tcx , vid) ;
0 commit comments