@@ -828,6 +828,8 @@ struct PlaceInfo<Cx: TypeCx> {
828828 ty : Cx :: Ty ,
829829 /// Whether the place is known to contain valid data.
830830 validity : ValidityConstraint ,
831+ /// Whether the place is the scrutinee itself or a subplace of it.
832+ is_scrutinee : bool ,
831833}
832834
833835impl < Cx : TypeCx > PlaceInfo < Cx > {
@@ -838,13 +840,17 @@ impl<Cx: TypeCx> PlaceInfo<Cx> {
838840 ) -> impl Iterator < Item = Self > + ExactSizeIterator + Captures < ' a > {
839841 let ctor_sub_tys = cx. ctor_sub_tys ( ctor, & self . ty ) ;
840842 let ctor_sub_validity = self . validity . specialize ( ctor) ;
841- ctor_sub_tys. map ( move |ty| PlaceInfo { ty, validity : ctor_sub_validity } )
843+ ctor_sub_tys. map ( move |ty| PlaceInfo {
844+ ty,
845+ validity : ctor_sub_validity,
846+ is_scrutinee : false ,
847+ } )
842848 }
843849}
844850
845851impl < Cx : TypeCx > Clone for PlaceInfo < Cx > {
846852 fn clone ( & self ) -> Self {
847- Self { ty : self . ty . clone ( ) , validity : self . validity }
853+ Self { ty : self . ty . clone ( ) , validity : self . validity , is_scrutinee : self . is_scrutinee }
848854 }
849855}
850856
@@ -1051,7 +1057,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10511057 scrut_ty : Cx :: Ty ,
10521058 scrut_validity : ValidityConstraint ,
10531059 ) -> Self {
1054- let place_info = PlaceInfo { ty : scrut_ty, validity : scrut_validity } ;
1060+ let place_info = PlaceInfo { ty : scrut_ty, validity : scrut_validity, is_scrutinee : true } ;
10551061 let mut matrix = Matrix {
10561062 rows : Vec :: with_capacity ( arms. len ( ) ) ,
10571063 place_info : smallvec ! [ place_info] ,
@@ -1446,11 +1452,10 @@ fn collect_overlapping_range_endpoints<'p, Cx: TypeCx>(
14461452/// - unspecialization, where we lift the results from the previous step into results for this step
14471453/// (using `apply_constructor` and by updating `row.useful` for each parent row).
14481454/// This is all explained at the top of the file.
1449- #[ instrument( level = "debug" , skip( mcx, is_top_level ) , ret) ]
1455+ #[ instrument( level = "debug" , skip( mcx) , ret) ]
14501456fn compute_exhaustiveness_and_usefulness < ' a , ' p , Cx : TypeCx > (
14511457 mcx : UsefulnessCtxt < ' a , Cx > ,
14521458 matrix : & mut Matrix < ' p , Cx > ,
1453- is_top_level : bool ,
14541459) -> Result < WitnessMatrix < Cx > , Cx :: Error > {
14551460 debug_assert ! ( matrix. rows( ) . all( |r| r. len( ) == matrix. column_count( ) ) ) ;
14561461
@@ -1488,7 +1493,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
14881493
14891494 // We treat match scrutinees of type `!` or `EmptyEnum` differently.
14901495 let is_toplevel_exception =
1491- is_top_level && matches ! ( ctors_for_ty, ConstructorSet :: NoConstructors ) ;
1496+ place . is_scrutinee && matches ! ( ctors_for_ty, ConstructorSet :: NoConstructors ) ;
14921497 // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
14931498 // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
14941499 let empty_arms_are_unreachable = place. validity . is_known_valid ( )
@@ -1517,7 +1522,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
15171522
15181523 // Decide what constructors to report.
15191524 let is_integers = matches ! ( ctors_for_ty, ConstructorSet :: Integers { .. } ) ;
1520- let always_report_all = is_top_level && !is_integers;
1525+ let always_report_all = place . is_scrutinee && !is_integers;
15211526 // Whether we should report "Enum::A and Enum::C are missing" or "_ is missing".
15221527 let report_individual_missing_ctors = always_report_all || !all_missing;
15231528 // Which constructors are considered missing. We ensure that `!missing_ctors.is_empty() =>
@@ -1538,7 +1543,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
15381543 let ctor_is_relevant = matches ! ( ctor, Constructor :: Missing ) || missing_ctors. is_empty ( ) ;
15391544 let mut spec_matrix = matrix. specialize_constructor ( pcx, & ctor, ctor_is_relevant) ?;
15401545 let mut witnesses = ensure_sufficient_stack ( || {
1541- compute_exhaustiveness_and_usefulness ( mcx, & mut spec_matrix, false )
1546+ compute_exhaustiveness_and_usefulness ( mcx, & mut spec_matrix)
15421547 } ) ?;
15431548
15441549 // Transform witnesses for `spec_matrix` into witnesses for `matrix`.
@@ -1613,8 +1618,7 @@ pub fn compute_match_usefulness<'p, Cx: TypeCx>(
16131618) -> Result < UsefulnessReport < ' p , Cx > , Cx :: Error > {
16141619 let cx = UsefulnessCtxt { tycx } ;
16151620 let mut matrix = Matrix :: new ( arms, scrut_ty, scrut_validity) ;
1616- let non_exhaustiveness_witnesses =
1617- compute_exhaustiveness_and_usefulness ( cx, & mut matrix, true ) ?;
1621+ let non_exhaustiveness_witnesses = compute_exhaustiveness_and_usefulness ( cx, & mut matrix) ?;
16181622
16191623 let non_exhaustiveness_witnesses: Vec < _ > = non_exhaustiveness_witnesses. single_column ( ) ;
16201624 let arm_usefulness: Vec < _ > = arms
0 commit comments