@@ -153,19 +153,14 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
153153 visit:: walk_expr ( cx, ex) ;
154154 match ex. node {
155155 ast:: ExprMatch ( ref scrut, ref arms, source) => {
156- // First, check legality of move bindings.
157156 for arm in arms. iter ( ) {
157+ // First, check legality of move bindings.
158158 check_legality_of_move_bindings ( cx,
159159 arm. guard . is_some ( ) ,
160160 arm. pats . as_slice ( ) ) ;
161- for pat in arm. pats . iter ( ) {
162- check_legality_of_bindings_in_at_patterns ( cx, & * * pat) ;
163- }
164- }
165161
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.
169164 match arm. guard {
170165 Some ( ref guard) => check_for_mutation_in_guard ( cx, & * * guard) ,
171166 None => { }
@@ -179,13 +174,23 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
179174 } ) . collect ( ) , arm. guard . as_ref ( ) . map ( |e| & * * e) )
180175 } ) . collect :: < Vec < ( Vec < P < Pat > > , Option < & ast:: Expr > ) > > ( ) ;
181176
177+ // Bail out early if inlining failed.
182178 if static_inliner. failed {
183179 return ;
184180 }
185181
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) ;
189194 }
190195
191196 // Fourth, check for unreachable arms.
@@ -239,21 +244,49 @@ fn is_expr_const_nan(tcx: &ty::ctxt, expr: &ast::Expr) -> bool {
239244 }
240245}
241246
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+ }
251269 }
252- _ => ( )
253270 }
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+ } ) ;
257290}
258291
259292// Check for unreachable patterns
@@ -414,8 +447,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
414447 & Variant ( vid) =>
415448 ( vid, ty:: enum_variant_with_id ( cx. tcx , cid, vid) . arg_names . is_some ( ) ) ,
416449 _ =>
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) )
419451 } ;
420452 if is_structure {
421453 let fields = ty:: lookup_struct_fields ( cx. tcx , vid) ;
0 commit comments