11use super :: deconstruct_pat:: { Constructor , DeconstructedPat } ;
22use super :: usefulness:: {
3- compute_match_usefulness, MatchArm , MatchCheckCtxt , Reachability , UsefulnessReport ,
3+ compute_match_usefulness, MatchArm , Reachability , UsefulnessCtxt , UsefulnessReport ,
44} ;
5- use super :: { deconstructed_to_pat, pat_to_deconstructed, PatCtxt , PatternError } ;
5+ use super :: { deconstructed_to_pat, pat_to_deconstructed, MatchCheckCtxt , PatCtxt , PatternError } ;
66
77use rustc_arena:: TypedArena ;
88use rustc_ast:: Mutability ;
@@ -51,7 +51,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
5151 tcx : TyCtxt < ' tcx > ,
5252 typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
5353 param_env : ty:: ParamEnv < ' tcx > ,
54- pattern_arena : & ' p TypedArena < DeconstructedPat < ' p , ' tcx > > ,
54+ pattern_arena : & ' p TypedArena < DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > > ,
5555}
5656
5757impl < ' tcx > Visitor < ' tcx > for MatchVisitor < ' _ , ' _ , ' tcx > {
@@ -128,10 +128,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
128128
129129 fn lower_pattern (
130130 & self ,
131- cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
131+ cx : & UsefulnessCtxt < ' p , MatchCheckCtxt < ' tcx > > ,
132132 pat : & ' tcx hir:: Pat < ' tcx > ,
133133 have_errors : & mut bool ,
134- ) -> & ' p DeconstructedPat < ' p , ' tcx > {
134+ ) -> & ' p DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > {
135135 let mut patcx = PatCtxt :: new ( self . tcx , self . param_env , self . typeck_results ) ;
136136 patcx. include_lint_checks ( ) ;
137137 let pattern = patcx. lower_pattern ( pat) ;
@@ -143,13 +143,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
143143 pattern
144144 }
145145
146- fn new_cx ( & self , hir_id : HirId ) -> MatchCheckCtxt < ' p , ' tcx > {
147- MatchCheckCtxt {
146+ fn new_cx ( & self , hir_id : HirId ) -> UsefulnessCtxt < ' p , MatchCheckCtxt < ' tcx > > {
147+ let cx = MatchCheckCtxt {
148148 tcx : self . tcx ,
149149 param_env : self . param_env ,
150150 module : self . tcx . parent_module ( hir_id) . to_def_id ( ) ,
151- pattern_arena : & self . pattern_arena ,
152- }
151+ } ;
152+ UsefulnessCtxt { cx , pattern_arena : & self . pattern_arena }
153153 }
154154
155155 fn check_let ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > , expr : & hir:: Expr < ' _ > , span : Span ) {
@@ -165,15 +165,16 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
165165 arms : & ' tcx [ hir:: Arm < ' tcx > ] ,
166166 source : hir:: MatchSource ,
167167 ) {
168- let mut cx = self . new_cx ( scrut. hir_id ) ;
168+ let ucx = self . new_cx ( scrut. hir_id ) ;
169+ let cx = & ucx. cx ;
169170
170171 for arm in arms {
171172 // Check the arm for some things unrelated to exhaustiveness.
172173 self . check_patterns ( & arm. pat , Refutable ) ;
173174 if let Some ( hir:: Guard :: IfLet ( ref pat, _) ) = arm. guard {
174175 self . check_patterns ( pat, Refutable ) ;
175- let tpat = self . lower_pattern ( & mut cx , pat, & mut false ) ;
176- check_let_reachability ( & mut cx , pat. hir_id , tpat, tpat. span ( ) ) ;
176+ let tpat = self . lower_pattern ( & ucx , pat, & mut false ) ;
177+ check_let_reachability ( & ucx , pat. hir_id , tpat, tpat. span ( ) ) ;
177178 }
178179 }
179180
@@ -182,7 +183,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
182183 let arms: Vec < _ > = arms
183184 . iter ( )
184185 . map ( |hir:: Arm { pat, guard, .. } | MatchArm {
185- pat : self . lower_pattern ( & mut cx , pat, & mut have_errors) ,
186+ pat : self . lower_pattern ( & ucx , pat, & mut have_errors) ,
186187 hir_id : pat. hir_id ,
187188 has_guard : guard. is_some ( ) ,
188189 } )
@@ -194,7 +195,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
194195 }
195196
196197 let scrut_ty = self . typeck_results . expr_ty_adjusted ( scrut) ;
197- let report = compute_match_usefulness ( & cx , & arms, scrut. hir_id , scrut_ty) ;
198+ let report = compute_match_usefulness ( & ucx , & arms, scrut. hir_id , scrut_ty) ;
198199
199200 match source {
200201 hir:: MatchSource :: ForLoopDesugar | hir:: MatchSource :: Normal => {
@@ -215,12 +216,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
215216 }
216217
217218 fn check_irrefutable ( & self , pat : & ' tcx Pat < ' tcx > , origin : & str , sp : Option < Span > ) {
218- let mut cx = self . new_cx ( pat. hir_id ) ;
219+ let ucx = self . new_cx ( pat. hir_id ) ;
220+ let cx = & ucx. cx ;
219221
220- let pattern = self . lower_pattern ( & mut cx , pat, & mut false ) ;
222+ let pattern = self . lower_pattern ( & ucx , pat, & mut false ) ;
221223 let pattern_ty = pattern. ty ( ) ;
222224 let arms = vec ! [ MatchArm { pat: pattern, hir_id: pat. hir_id, has_guard: false } ] ;
223- let report = compute_match_usefulness ( & cx , & arms, pat. hir_id , pattern_ty) ;
225+ let report = compute_match_usefulness ( & ucx , & arms, pat. hir_id , pattern_ty) ;
224226 report_exhaustiveness_lints ( & cx, & report) ;
225227
226228 // Note: we ignore whether the pattern is unreachable (i.e. whether the type is empty). We
@@ -359,7 +361,7 @@ fn check_for_bindings_named_same_as_variants(
359361}
360362
361363/// Checks for common cases of "catchall" patterns that may not be intended as such.
362- fn pat_is_catchall ( pat : & DeconstructedPat < ' _ , ' _ > ) -> bool {
364+ fn pat_is_catchall ( pat : & DeconstructedPat < ' _ , MatchCheckCtxt < ' _ > > ) -> bool {
363365 use Constructor :: * ;
364366 match pat. ctor ( ) {
365367 Wildcard => true ,
@@ -440,13 +442,14 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
440442}
441443
442444fn check_let_reachability < ' p , ' tcx > (
443- cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
445+ ucx : & UsefulnessCtxt < ' p , MatchCheckCtxt < ' tcx > > ,
444446 pat_id : HirId ,
445- pat : & ' p DeconstructedPat < ' p , ' tcx > ,
447+ pat : & ' p DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > ,
446448 span : Span ,
447449) {
450+ let cx = & ucx. cx ;
448451 let arms = [ MatchArm { pat, hir_id : pat_id, has_guard : false } ] ;
449- let report = compute_match_usefulness ( & cx , & arms, pat_id, pat. ty ( ) ) ;
452+ let report = compute_match_usefulness ( & ucx , & arms, pat_id, pat. ty ( ) ) ;
450453 report_exhaustiveness_lints ( & cx, & report) ;
451454
452455 // Report if the pattern is unreachable, which can only occur when the type is uninhabited.
@@ -460,8 +463,8 @@ fn check_let_reachability<'p, 'tcx>(
460463
461464/// Report unreachable arms, if any.
462465fn report_arm_reachability < ' p , ' tcx > (
463- cx : & MatchCheckCtxt < ' p , ' tcx > ,
464- report : & UsefulnessReport < ' p , ' tcx > ,
466+ cx : & MatchCheckCtxt < ' tcx > ,
467+ report : & UsefulnessReport < ' p , MatchCheckCtxt < ' tcx > > ,
465468) {
466469 let mut catchall = None ;
467470 for ( arm, reachability) in report. arm_usefulness . iter ( ) {
@@ -479,8 +482,8 @@ fn report_arm_reachability<'p, 'tcx>(
479482
480483/// Report various things detected during exhaustiveness checking.
481484fn report_exhaustiveness_lints < ' p , ' tcx > (
482- cx : & MatchCheckCtxt < ' p , ' tcx > ,
483- report : & UsefulnessReport < ' p , ' tcx > ,
485+ cx : & MatchCheckCtxt < ' tcx > ,
486+ report : & UsefulnessReport < ' p , MatchCheckCtxt < ' tcx > > ,
484487) {
485488 if !report. unreachable_subpatterns . is_empty ( ) {
486489 let mut unreachables = report. unreachable_subpatterns . clone ( ) ;
@@ -502,11 +505,11 @@ fn report_exhaustiveness_lints<'p, 'tcx>(
502505///
503506/// NB: The partner lint for structs lives in `compiler/rustc_typeck/src/check/pat.rs`.
504507pub ( super ) fn lint_non_exhaustive_omitted_patterns < ' p , ' tcx > (
505- cx : & MatchCheckCtxt < ' p , ' tcx > ,
508+ cx : & MatchCheckCtxt < ' tcx > ,
506509 scrut_ty : Ty < ' tcx > ,
507510 span : Span ,
508511 hir_id : HirId ,
509- witnesses : & [ DeconstructedPat < ' p , ' tcx > ] ,
512+ witnesses : & [ DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > ] ,
510513) {
511514 let joined_patterns = joined_uncovered_patterns ( cx, & witnesses) ;
512515 cx. tcx . struct_span_lint_hir ( NON_EXHAUSTIVE_OMITTED_PATTERNS , hir_id, span, |build| {
@@ -525,10 +528,10 @@ pub(super) fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
525528
526529/// Lint on likely incorrect range patterns (#63987)
527530pub ( super ) fn lint_overlapping_range_endpoints < ' p , ' tcx > (
528- cx : & MatchCheckCtxt < ' p , ' tcx > ,
531+ cx : & MatchCheckCtxt < ' tcx > ,
529532 span : Span ,
530533 hir_id : HirId ,
531- overlaps : & [ DeconstructedPat < ' p , ' tcx > ] ,
534+ overlaps : & [ DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > ] ,
532535) {
533536 if !overlaps. is_empty ( ) {
534537 cx. tcx . struct_span_lint_hir ( OVERLAPPING_RANGE_ENDPOINTS , hir_id, span, |lint| {
@@ -548,10 +551,10 @@ pub(super) fn lint_overlapping_range_endpoints<'p, 'tcx>(
548551
549552/// Report that a match is not exhaustive.
550553fn non_exhaustive_match < ' p , ' tcx > (
551- cx : & MatchCheckCtxt < ' p , ' tcx > ,
554+ cx : & MatchCheckCtxt < ' tcx > ,
552555 scrut_ty : Ty < ' tcx > ,
553556 sp : Span ,
554- witnesses : Vec < DeconstructedPat < ' p , ' tcx > > ,
557+ witnesses : Vec < DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > > ,
555558 is_empty_match : bool ,
556559) {
557560 let non_empty_enum = match scrut_ty. kind ( ) {
@@ -619,8 +622,8 @@ fn non_exhaustive_match<'p, 'tcx>(
619622}
620623
621624crate fn joined_uncovered_patterns < ' p , ' tcx > (
622- cx : & MatchCheckCtxt < ' p , ' tcx > ,
623- witnesses : & [ DeconstructedPat < ' p , ' tcx > ] ,
625+ cx : & MatchCheckCtxt < ' tcx > ,
626+ witnesses : & [ DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > ] ,
624627) -> String {
625628 const LIMIT : usize = 3 ;
626629 let pat_to_str = |pat| deconstructed_to_pat ( cx, pat) . to_string ( ) ;
@@ -640,18 +643,18 @@ crate fn joined_uncovered_patterns<'p, 'tcx>(
640643}
641644
642645crate fn pattern_not_covered_label (
643- witnesses : & [ DeconstructedPat < ' _ , ' _ > ] ,
646+ witnesses : & [ DeconstructedPat < ' _ , MatchCheckCtxt < ' _ > > ] ,
644647 joined_patterns : & str ,
645648) -> String {
646649 format ! ( "pattern{} {} not covered" , rustc_errors:: pluralize!( witnesses. len( ) ) , joined_patterns)
647650}
648651
649652/// Point at the definition of non-covered `enum` variants.
650653fn adt_defined_here < ' p , ' tcx > (
651- cx : & MatchCheckCtxt < ' p , ' tcx > ,
654+ cx : & MatchCheckCtxt < ' tcx > ,
652655 err : & mut DiagnosticBuilder < ' _ > ,
653656 ty : Ty < ' tcx > ,
654- witnesses : & [ DeconstructedPat < ' p , ' tcx > ] ,
657+ witnesses : & [ DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > ] ,
655658) {
656659 let ty = ty. peel_refs ( ) ;
657660 if let ty:: Adt ( def, _) = ty. kind ( ) {
@@ -668,10 +671,13 @@ fn adt_defined_here<'p, 'tcx>(
668671}
669672
670673fn maybe_point_at_variant < ' a , ' p : ' a , ' tcx : ' a > (
671- cx : & MatchCheckCtxt < ' p , ' tcx > ,
674+ cx : & MatchCheckCtxt < ' tcx > ,
672675 def : & AdtDef ,
673- patterns : impl Iterator < Item = & ' a DeconstructedPat < ' p , ' tcx > > ,
674- ) -> Vec < Span > {
676+ patterns : impl Iterator < Item = & ' a DeconstructedPat < ' p , MatchCheckCtxt < ' tcx > > > ,
677+ ) -> Vec < Span >
678+ where
679+ MatchCheckCtxt < ' tcx > : ' p ,
680+ {
675681 use Constructor :: * ;
676682 let mut covered = vec ! [ ] ;
677683 for pattern in patterns {
0 commit comments