@@ -48,6 +48,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
4848 struct_has_extern_repr : bool ,
4949 ignore_non_const_paths : bool ,
5050 inherited_pub_visibility : bool ,
51+ ignore_variant_stack : Vec < ast:: NodeId > ,
5152}
5253
5354impl < ' a , ' tcx > MarkSymbolVisitor < ' a , ' tcx > {
@@ -60,6 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
6061 struct_has_extern_repr : false ,
6162 ignore_non_const_paths : false ,
6263 inherited_pub_visibility : false ,
64+ ignore_variant_stack : vec ! [ ] ,
6365 }
6466 }
6567
@@ -80,7 +82,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
8082 def:: DefPrimTy ( _) => ( ) ,
8183 def:: DefVariant ( enum_id, variant_id, _) => {
8284 self . check_def_id ( enum_id) ;
83- self . check_def_id ( variant_id) ;
85+ if !self . ignore_variant_stack . contains ( & variant_id. node ) {
86+ self . check_def_id ( variant_id) ;
87+ }
8488 }
8589 _ => {
8690 self . check_def_id ( def. def_id ( ) ) ;
@@ -272,6 +276,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
272276 visit:: walk_expr ( self , expr) ;
273277 }
274278
279+ fn visit_arm ( & mut self , arm : & ast:: Arm ) {
280+ if arm. pats . len ( ) == 1 {
281+ let pat = & * arm. pats [ 0 ] ;
282+ let variants = pat_util:: necessary_variants ( & self . tcx . def_map , pat) ;
283+
284+ // Inside the body, ignore constructions of variants
285+ // necessary for the pattern to match. Those construction sites
286+ // can't be reached unless the variant is constructed elsewhere.
287+ let len = self . ignore_variant_stack . len ( ) ;
288+ self . ignore_variant_stack . push_all ( & * variants) ;
289+ visit:: walk_arm ( self , arm) ;
290+ self . ignore_variant_stack . truncate ( len) ;
291+ } else {
292+ visit:: walk_arm ( self , arm) ;
293+ }
294+ }
295+
275296 fn visit_pat ( & mut self , pat : & ast:: Pat ) {
276297 let def_map = & self . tcx . def_map ;
277298 match pat. node {
@@ -393,6 +414,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
393414 worklist. push ( * id) ;
394415 }
395416 for id in reachable_symbols {
417+ // Reachable variants can be dead, because we warn about
418+ // variants never constructed, not variants never used.
419+ if let Some ( ast_map:: NodeVariant ( ..) ) = tcx. map . find ( * id) {
420+ continue ;
421+ }
396422 worklist. push ( * id) ;
397423 }
398424
0 commit comments