@@ -47,6 +47,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
4747 struct_has_extern_repr : bool ,
4848 ignore_non_const_paths : bool ,
4949 inherited_pub_visibility : bool ,
50+ ignore_variant_stack : Vec < ast:: NodeId > ,
5051}
5152
5253impl < ' a , ' tcx > MarkSymbolVisitor < ' a , ' tcx > {
@@ -59,6 +60,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
5960 struct_has_extern_repr : false ,
6061 ignore_non_const_paths : false ,
6162 inherited_pub_visibility : false ,
63+ ignore_variant_stack : vec ! [ ] ,
6264 }
6365 }
6466
@@ -79,7 +81,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
7981 & def:: DefPrimTy ( _) => ( ) ,
8082 & def:: DefVariant ( enum_id, variant_id, _) => {
8183 self . check_def_id ( enum_id) ;
82- self . check_def_id ( variant_id) ;
84+ if !self . ignore_variant_stack . contains ( & variant_id. node ) {
85+ self . check_def_id ( variant_id) ;
86+ }
8387 }
8488 _ => {
8589 self . check_def_id ( def. def_id ( ) ) ;
@@ -283,6 +287,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
283287 visit:: walk_expr ( self , expr) ;
284288 }
285289
290+ fn visit_arm ( & mut self , arm : & ast:: Arm ) {
291+ if arm. pats . len ( ) == 1 {
292+ let pat = & * arm. pats [ 0 ] ;
293+ let variants = pat_util:: necessary_variants ( & self . tcx . def_map , pat) ;
294+
295+ // Inside the body, ignore constructions of variants
296+ // necessary for the pattern to match. Those construction sites
297+ // can't be reached unless the variant is constructed elsewhere.
298+ let len = self . ignore_variant_stack . len ( ) ;
299+ self . ignore_variant_stack . push_all ( & * variants) ;
300+ visit:: walk_arm ( self , arm) ;
301+ self . ignore_variant_stack . truncate ( len) ;
302+ } else {
303+ visit:: walk_arm ( self , arm) ;
304+ }
305+ }
306+
286307 fn visit_pat ( & mut self , pat : & ast:: Pat ) {
287308 let def_map = & self . tcx . def_map ;
288309 match pat. node {
@@ -401,6 +422,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
401422 worklist. push ( * id) ;
402423 }
403424 for id in reachable_symbols {
425+ // Reachable variants can be dead, because we warn about
426+ // variants never constructed, not variants never used.
427+ if let Some ( ast_map:: NodeVariant ( ..) ) = tcx. map . find ( * id) {
428+ continue ;
429+ }
404430 worklist. push ( * id) ;
405431 }
406432
0 commit comments