@@ -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] ,
@@ -1456,11 +1462,10 @@ fn collect_overlapping_range_endpoints<'p, Cx: TypeCx>(
14561462/// - unspecialization, where we lift the results from the previous step into results for this step
14571463/// (using `apply_constructor` and by updating `row.useful` for each parent row).
14581464/// This is all explained at the top of the file.
1459- #[ instrument( level = "debug" , skip( mcx, is_top_level ) , ret) ]
1465+ #[ instrument( level = "debug" , skip( mcx) , ret) ]
14601466fn compute_exhaustiveness_and_usefulness < ' a , ' p , Cx : TypeCx > (
14611467 mcx : UsefulnessCtxt < ' a , Cx > ,
14621468 matrix : & mut Matrix < ' p , Cx > ,
1463- is_top_level : bool ,
14641469) -> Result < WitnessMatrix < Cx > , Cx :: Error > {
14651470 debug_assert ! ( matrix. rows( ) . all( |r| r. len( ) == matrix. column_count( ) ) ) ;
14661471
@@ -1498,7 +1503,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
14981503
14991504 // We treat match scrutinees of type `!` or `EmptyEnum` differently.
15001505 let is_toplevel_exception =
1501- is_top_level && matches ! ( ctors_for_ty, ConstructorSet :: NoConstructors ) ;
1506+ place . is_scrutinee && matches ! ( ctors_for_ty, ConstructorSet :: NoConstructors ) ;
15021507 // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
15031508 // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
15041509 let empty_arms_are_unreachable = place. validity . is_known_valid ( )
@@ -1527,7 +1532,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
15271532
15281533 // Decide what constructors to report.
15291534 let is_integers = matches ! ( ctors_for_ty, ConstructorSet :: Integers { .. } ) ;
1530- let always_report_all = is_top_level && !is_integers;
1535+ let always_report_all = place . is_scrutinee && !is_integers;
15311536 // Whether we should report "Enum::A and Enum::C are missing" or "_ is missing".
15321537 let report_individual_missing_ctors = always_report_all || !all_missing;
15331538 // Which constructors are considered missing. We ensure that `!missing_ctors.is_empty() =>
@@ -1548,7 +1553,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
15481553 let ctor_is_relevant = matches ! ( ctor, Constructor :: Missing ) || missing_ctors. is_empty ( ) ;
15491554 let mut spec_matrix = matrix. specialize_constructor ( pcx, & ctor, ctor_is_relevant) ?;
15501555 let mut witnesses = ensure_sufficient_stack ( || {
1551- compute_exhaustiveness_and_usefulness ( mcx, & mut spec_matrix, false )
1556+ compute_exhaustiveness_and_usefulness ( mcx, & mut spec_matrix)
15521557 } ) ?;
15531558
15541559 // Transform witnesses for `spec_matrix` into witnesses for `matrix`.
@@ -1623,8 +1628,7 @@ pub fn compute_match_usefulness<'p, Cx: TypeCx>(
16231628) -> Result < UsefulnessReport < ' p , Cx > , Cx :: Error > {
16241629 let cx = UsefulnessCtxt { tycx } ;
16251630 let mut matrix = Matrix :: new ( arms, scrut_ty, scrut_validity) ;
1626- let non_exhaustiveness_witnesses =
1627- compute_exhaustiveness_and_usefulness ( cx, & mut matrix, true ) ?;
1631+ let non_exhaustiveness_witnesses = compute_exhaustiveness_and_usefulness ( cx, & mut matrix) ?;
16281632
16291633 let non_exhaustiveness_witnesses: Vec < _ > = non_exhaustiveness_witnesses. single_column ( ) ;
16301634 let arm_usefulness: Vec < _ > = arms
0 commit comments