44// is dead.
55
66use std:: mem;
7+ use std:: ops:: ControlFlow ;
78
89use hir:: def_id:: { LocalDefIdMap , LocalDefIdSet } ;
910use rustc_abi:: FieldIdx ;
1011use rustc_data_structures:: fx:: FxIndexSet ;
11- use rustc_errors:: MultiSpan ;
12+ use rustc_errors:: { ErrorGuaranteed , MultiSpan } ;
1213use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
1314use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId } ;
1415use rustc_hir:: intravisit:: { self , Visitor } ;
@@ -178,12 +179,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
178179 . iter ( )
179180 . any ( |adj| matches ! ( adj. kind, ty:: adjustment:: Adjust :: Deref ( _) ) )
180181 {
181- self . visit_expr ( expr) ;
182+ let _ = self . visit_expr ( expr) ;
182183 } else if let hir:: ExprKind :: Field ( base, ..) = expr. kind {
183184 // Ignore write to field
184185 self . handle_assign ( base) ;
185186 } else {
186- self . visit_expr ( expr) ;
187+ let _ = self . visit_expr ( expr) ;
187188 }
188189 }
189190
@@ -318,7 +319,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
318319 }
319320 }
320321
321- fn mark_live_symbols ( & mut self ) {
322+ fn mark_live_symbols ( & mut self ) -> < MarkSymbolVisitor < ' tcx > as Visitor < ' tcx > > :: Result {
322323 while let Some ( work) = self . worklist . pop ( ) {
323324 let ( mut id, comes_from_allow_expect) = work;
324325
@@ -366,8 +367,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
366367 continue ;
367368 }
368369
369- self . visit_node ( self . tcx . hir_node_by_def_id ( id) ) ;
370+ let visit_result = self . visit_node ( self . tcx . hir_node_by_def_id ( id) ) ;
371+ if visit_result. is_break ( ) {
372+ return visit_result;
373+ }
370374 }
375+
376+ ControlFlow :: Continue ( ( ) )
371377 }
372378
373379 /// Automatically generated items marked with `rustc_trivial_field_reads`
@@ -395,19 +401,22 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
395401 false
396402 }
397403
398- fn visit_node ( & mut self , node : Node < ' tcx > ) {
404+ fn visit_node (
405+ & mut self ,
406+ node : Node < ' tcx > ,
407+ ) -> <MarkSymbolVisitor < ' tcx > as Visitor < ' tcx > >:: Result {
399408 if let Node :: ImplItem ( hir:: ImplItem { owner_id, .. } ) = node
400409 && self . should_ignore_item ( owner_id. to_def_id ( ) )
401410 {
402- return ;
411+ return ControlFlow :: Continue ( ( ) ) ;
403412 }
404413
405414 let unconditionally_treated_fields_as_live =
406415 self . repr_unconditionally_treats_fields_as_live ;
407416 let had_repr_simd = self . repr_has_repr_simd ;
408417 self . repr_unconditionally_treats_fields_as_live = false ;
409418 self . repr_has_repr_simd = false ;
410- match node {
419+ let walk_result = match node {
411420 Node :: Item ( item) => match item. kind {
412421 hir:: ItemKind :: Struct ( ..) | hir:: ItemKind :: Union ( ..) => {
413422 let def = self . tcx . adt_def ( item. owner_id ) ;
@@ -417,7 +426,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
417426
418427 intravisit:: walk_item ( self , item)
419428 }
420- hir:: ItemKind :: ForeignMod { .. } => { }
429+ hir:: ItemKind :: ForeignMod { .. } => ControlFlow :: Continue ( ( ) ) ,
421430 hir:: ItemKind :: Trait ( .., trait_item_refs) => {
422431 // mark assoc ty live if the trait is live
423432 for trait_item in trait_item_refs {
@@ -435,7 +444,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
435444 if let Some ( trait_id) = self . tcx . trait_of_assoc ( trait_item_id) {
436445 self . check_def_id ( trait_id) ;
437446 }
438- intravisit:: walk_trait_item ( self , trait_item) ;
447+ intravisit:: walk_trait_item ( self , trait_item)
439448 }
440449 Node :: ImplItem ( impl_item) => {
441450 let item = self . tcx . local_parent ( impl_item. owner_id . def_id ) ;
@@ -456,16 +465,16 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
456465 _ => { }
457466 }
458467 }
459- intravisit:: walk_impl_item ( self , impl_item) ;
460- }
461- Node :: ForeignItem ( foreign_item) => {
462- intravisit:: walk_foreign_item ( self , foreign_item) ;
468+ intravisit:: walk_impl_item ( self , impl_item)
463469 }
470+ Node :: ForeignItem ( foreign_item) => intravisit:: walk_foreign_item ( self , foreign_item) ,
464471 Node :: OpaqueTy ( opaq) => intravisit:: walk_opaque_ty ( self , opaq) ,
465- _ => { }
466- }
472+ _ => ControlFlow :: Continue ( ( ) ) ,
473+ } ;
467474 self . repr_has_repr_simd = had_repr_simd;
468475 self . repr_unconditionally_treats_fields_as_live = unconditionally_treated_fields_as_live;
476+
477+ walk_result
469478 }
470479
471480 fn mark_as_used_if_union ( & mut self , adt : ty:: AdtDef < ' tcx > , fields : & [ hir:: ExprField < ' _ > ] ) {
@@ -520,21 +529,25 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
520529}
521530
522531impl < ' tcx > Visitor < ' tcx > for MarkSymbolVisitor < ' tcx > {
523- fn visit_nested_body ( & mut self , body : hir:: BodyId ) {
532+ type Result = ControlFlow < ErrorGuaranteed > ;
533+
534+ fn visit_nested_body ( & mut self , body : hir:: BodyId ) -> Self :: Result {
524535 let typeck_results = self . tcx . typeck_body ( body) ;
525536
526537 // The result shouldn't be tainted, otherwise it will cause ICE.
527- if typeck_results. tainted_by_errors . is_some ( ) {
528- return ;
538+ if let Some ( guar ) = typeck_results. tainted_by_errors {
539+ return ControlFlow :: Break ( guar ) ;
529540 }
530541
531542 let old_maybe_typeck_results = self . maybe_typeck_results . replace ( typeck_results) ;
532543 let body = self . tcx . hir_body ( body) ;
533- self . visit_body ( body) ;
544+ let result = self . visit_body ( body) ;
534545 self . maybe_typeck_results = old_maybe_typeck_results;
546+
547+ result
535548 }
536549
537- fn visit_variant_data ( & mut self , def : & ' tcx hir:: VariantData < ' tcx > ) {
550+ fn visit_variant_data ( & mut self , def : & ' tcx hir:: VariantData < ' tcx > ) -> Self :: Result {
538551 let tcx = self . tcx ;
539552 let unconditionally_treat_fields_as_live = self . repr_unconditionally_treats_fields_as_live ;
540553 let has_repr_simd = self . repr_has_repr_simd ;
@@ -551,10 +564,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
551564 } ) ;
552565 self . live_symbols . extend ( live_fields) ;
553566
554- intravisit:: walk_struct_def ( self , def) ;
567+ intravisit:: walk_struct_def ( self , def)
555568 }
556569
557- fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) {
570+ fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) -> Self :: Result {
558571 match expr. kind {
559572 hir:: ExprKind :: Path ( ref qpath @ QPath :: TypeRelative ( ..) ) => {
560573 let res = self . typeck_results ( ) . qpath_res ( qpath, expr. hir_id ) ;
@@ -590,20 +603,22 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
590603 _ => ( ) ,
591604 }
592605
593- intravisit:: walk_expr ( self , expr) ;
606+ intravisit:: walk_expr ( self , expr)
594607 }
595608
596- fn visit_arm ( & mut self , arm : & ' tcx hir:: Arm < ' tcx > ) {
609+ fn visit_arm ( & mut self , arm : & ' tcx hir:: Arm < ' tcx > ) -> Self :: Result {
597610 // Inside the body, ignore constructions of variants
598611 // necessary for the pattern to match. Those construction sites
599612 // can't be reached unless the variant is constructed elsewhere.
600613 let len = self . ignore_variant_stack . len ( ) ;
601614 self . ignore_variant_stack . extend ( arm. pat . necessary_variants ( ) ) ;
602- intravisit:: walk_arm ( self , arm) ;
615+ let result = intravisit:: walk_arm ( self , arm) ;
603616 self . ignore_variant_stack . truncate ( len) ;
617+
618+ result
604619 }
605620
606- fn visit_pat ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > ) {
621+ fn visit_pat ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > ) -> Self :: Result {
607622 self . in_pat = true ;
608623 match pat. kind {
609624 PatKind :: Struct ( ref path, fields, _) => {
@@ -617,11 +632,13 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
617632 _ => ( ) ,
618633 }
619634
620- intravisit:: walk_pat ( self , pat) ;
635+ let result = intravisit:: walk_pat ( self , pat) ;
621636 self . in_pat = false ;
637+
638+ result
622639 }
623640
624- fn visit_pat_expr ( & mut self , expr : & ' tcx rustc_hir:: PatExpr < ' tcx > ) {
641+ fn visit_pat_expr ( & mut self , expr : & ' tcx rustc_hir:: PatExpr < ' tcx > ) -> Self :: Result {
625642 match & expr. kind {
626643 rustc_hir:: PatExprKind :: Path ( qpath) => {
627644 // mark the type of variant live when meeting E::V in expr
@@ -634,37 +651,41 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
634651 }
635652 _ => { }
636653 }
637- intravisit:: walk_pat_expr ( self , expr) ;
654+ intravisit:: walk_pat_expr ( self , expr)
638655 }
639656
640- fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , _: hir:: HirId ) {
657+ fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , _: hir:: HirId ) -> Self :: Result {
641658 self . handle_res ( path. res ) ;
642- intravisit:: walk_path ( self , path) ;
659+ intravisit:: walk_path ( self , path)
643660 }
644661
645- fn visit_anon_const ( & mut self , c : & ' tcx hir:: AnonConst ) {
662+ fn visit_anon_const ( & mut self , c : & ' tcx hir:: AnonConst ) -> Self :: Result {
646663 // When inline const blocks are used in pattern position, paths
647664 // referenced by it should be considered as used.
648665 let in_pat = mem:: replace ( & mut self . in_pat , false ) ;
649666
650667 self . live_symbols . insert ( c. def_id ) ;
651- intravisit:: walk_anon_const ( self , c) ;
668+ let result = intravisit:: walk_anon_const ( self , c) ;
652669
653670 self . in_pat = in_pat;
671+
672+ result
654673 }
655674
656- fn visit_inline_const ( & mut self , c : & ' tcx hir:: ConstBlock ) {
675+ fn visit_inline_const ( & mut self , c : & ' tcx hir:: ConstBlock ) -> Self :: Result {
657676 // When inline const blocks are used in pattern position, paths
658677 // referenced by it should be considered as used.
659678 let in_pat = mem:: replace ( & mut self . in_pat , false ) ;
660679
661680 self . live_symbols . insert ( c. def_id ) ;
662- intravisit:: walk_inline_const ( self , c) ;
681+ let result = intravisit:: walk_inline_const ( self , c) ;
663682
664683 self . in_pat = in_pat;
684+
685+ result
665686 }
666687
667- fn visit_trait_ref ( & mut self , t : & ' tcx hir:: TraitRef < ' tcx > ) {
688+ fn visit_trait_ref ( & mut self , t : & ' tcx hir:: TraitRef < ' tcx > ) -> Self :: Result {
668689 if let Some ( trait_def_id) = t. path . res . opt_def_id ( )
669690 && let Some ( segment) = t. path . segments . last ( )
670691 && let Some ( args) = segment. args
@@ -686,7 +707,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
686707 }
687708 }
688709
689- intravisit:: walk_trait_ref ( self , t) ;
710+ intravisit:: walk_trait_ref ( self , t)
690711 }
691712}
692713
@@ -833,7 +854,7 @@ fn create_and_seed_worklist(
833854fn live_symbols_and_ignored_derived_traits (
834855 tcx : TyCtxt < ' _ > ,
835856 ( ) : ( ) ,
836- ) -> ( LocalDefIdSet , LocalDefIdMap < FxIndexSet < DefId > > ) {
857+ ) -> Result < ( LocalDefIdSet , LocalDefIdMap < FxIndexSet < DefId > > ) , ErrorGuaranteed > {
837858 let ( worklist, mut unsolved_items) = create_and_seed_worklist ( tcx) ;
838859 let mut symbol_visitor = MarkSymbolVisitor {
839860 worklist,
@@ -847,7 +868,9 @@ fn live_symbols_and_ignored_derived_traits(
847868 ignore_variant_stack : vec ! [ ] ,
848869 ignored_derived_traits : Default :: default ( ) ,
849870 } ;
850- symbol_visitor. mark_live_symbols ( ) ;
871+ if let ControlFlow :: Break ( guar) = symbol_visitor. mark_live_symbols ( ) {
872+ return Err ( guar) ;
873+ }
851874
852875 // We have marked the primary seeds as live. We now need to process unsolved items from traits
853876 // and trait impls: add them to the work list if the trait or the implemented type is live.
@@ -861,14 +884,16 @@ fn live_symbols_and_ignored_derived_traits(
861884 symbol_visitor
862885 . worklist
863886 . extend ( items_to_check. drain ( ..) . map ( |id| ( id, ComesFromAllowExpect :: No ) ) ) ;
864- symbol_visitor. mark_live_symbols ( ) ;
887+ if let ControlFlow :: Break ( guar) = symbol_visitor. mark_live_symbols ( ) {
888+ return Err ( guar) ;
889+ }
865890
866891 items_to_check. extend ( unsolved_items. extract_if ( .., |& mut local_def_id| {
867892 symbol_visitor. check_impl_or_impl_item_live ( local_def_id)
868893 } ) ) ;
869894 }
870895
871- ( symbol_visitor. live_symbols , symbol_visitor. ignored_derived_traits )
896+ Ok ( ( symbol_visitor. live_symbols , symbol_visitor. ignored_derived_traits ) )
872897}
873898
874899struct DeadItem {
@@ -1148,7 +1173,11 @@ impl<'tcx> DeadVisitor<'tcx> {
11481173}
11491174
11501175fn check_mod_deathness ( tcx : TyCtxt < ' _ > , module : LocalModDefId ) {
1151- let ( live_symbols, ignored_derived_traits) = tcx. live_symbols_and_ignored_derived_traits ( ( ) ) ;
1176+ let live_symbols_result = tcx. live_symbols_and_ignored_derived_traits ( ( ) ) ;
1177+ if live_symbols_result. is_err ( ) {
1178+ return ;
1179+ }
1180+ let ( live_symbols, ignored_derived_traits) = live_symbols_result. as_ref ( ) . unwrap ( ) ;
11521181 let mut visitor = DeadVisitor { tcx, live_symbols, ignored_derived_traits } ;
11531182
11541183 let module_items = tcx. hir_module_items ( module) ;
0 commit comments