@@ -14,14 +14,17 @@ extern crate rustc_middle;
14
14
15
15
rustc_fluent_macro:: fluent_messages! { "../messages.ftl" }
16
16
17
- use lints:: PatternColumn ;
18
17
use rustc_hir:: HirId ;
19
- use rustc_middle:: ty:: Ty ;
20
- use usefulness :: { compute_match_usefulness , UsefulnessReport } ;
18
+ use rustc_middle:: ty:: { self , Ty } ;
19
+ use rustc_session :: lint ;
21
20
22
21
use crate :: cx:: MatchCheckCtxt ;
23
- use crate :: lints:: { lint_nonexhaustive_missing_variants, lint_overlapping_range_endpoints} ;
22
+ use crate :: errors:: { EmptyMatchOnUnsafePlace , EmptyMatchOnUnsafePlaceWrapSuggestion } ;
23
+ use crate :: lints:: {
24
+ lint_nonexhaustive_missing_variants, lint_overlapping_range_endpoints, PatternColumn ,
25
+ } ;
24
26
use crate :: pat:: DeconstructedPat ;
27
+ use crate :: usefulness:: { compute_match_usefulness, UsefulnessReport } ;
25
28
26
29
/// The arm of a match expression.
27
30
#[ derive( Clone , Copy , Debug ) ]
@@ -41,6 +44,40 @@ pub fn analyze_match<'p, 'tcx>(
41
44
) -> UsefulnessReport < ' p , ' tcx > {
42
45
let pat_column = PatternColumn :: new ( arms) ;
43
46
47
+ if !cx. known_valid_scrutinee && arms. iter ( ) . all ( |arm| arm. has_guard ) {
48
+ let is_directly_empty = match scrut_ty. kind ( ) {
49
+ ty:: Adt ( def, ..) => {
50
+ def. is_enum ( )
51
+ && def. variants ( ) . is_empty ( )
52
+ && !cx. is_foreign_non_exhaustive_enum ( scrut_ty)
53
+ }
54
+ ty:: Never => true ,
55
+ _ => false ,
56
+ } ;
57
+ if is_directly_empty {
58
+ if cx. tcx . features ( ) . min_exhaustive_patterns {
59
+ cx. tcx . emit_spanned_lint (
60
+ lint:: builtin:: EMPTY_MATCH_ON_UNSAFE_PLACE ,
61
+ cx. match_lint_level ,
62
+ cx. whole_match_span . unwrap_or ( cx. scrut_span ) ,
63
+ EmptyMatchOnUnsafePlace {
64
+ scrut_span : cx. scrut_span ,
65
+ suggestion : EmptyMatchOnUnsafePlaceWrapSuggestion {
66
+ scrut_start : cx. scrut_span . shrink_to_lo ( ) ,
67
+ scrut_end : cx. scrut_span . shrink_to_hi ( ) ,
68
+ } ,
69
+ } ,
70
+ ) ;
71
+ }
72
+
73
+ // For backwards compability we allow an empty match in this case.
74
+ return UsefulnessReport {
75
+ arm_usefulness : Vec :: new ( ) ,
76
+ non_exhaustiveness_witnesses : Vec :: new ( ) ,
77
+ } ;
78
+ }
79
+ }
80
+
44
81
let report = compute_match_usefulness ( cx, arms, scrut_ty) ;
45
82
46
83
// Lint on ranges that overlap on their endpoints, which is likely a mistake.
0 commit comments