@@ -48,6 +48,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
48
48
struct_has_extern_repr : bool ,
49
49
ignore_non_const_paths : bool ,
50
50
inherited_pub_visibility : bool ,
51
+ ignore_variant_stack : Vec < ast:: NodeId > ,
51
52
}
52
53
53
54
impl < ' a , ' tcx > MarkSymbolVisitor < ' a , ' tcx > {
@@ -60,6 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
60
61
struct_has_extern_repr : false ,
61
62
ignore_non_const_paths : false ,
62
63
inherited_pub_visibility : false ,
64
+ ignore_variant_stack : vec ! [ ] ,
63
65
}
64
66
}
65
67
@@ -80,7 +82,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
80
82
def:: DefPrimTy ( _) => ( ) ,
81
83
def:: DefVariant ( enum_id, variant_id, _) => {
82
84
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
+ }
84
88
}
85
89
_ => {
86
90
self . check_def_id ( def. def_id ( ) ) ;
@@ -272,6 +276,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
272
276
visit:: walk_expr ( self , expr) ;
273
277
}
274
278
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
+
275
296
fn visit_pat ( & mut self , pat : & ast:: Pat ) {
276
297
let def_map = & self . tcx . def_map ;
277
298
match pat. node {
@@ -393,6 +414,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
393
414
worklist. push ( * id) ;
394
415
}
395
416
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
+ }
396
422
worklist. push ( * id) ;
397
423
}
398
424
0 commit comments