@@ -1025,11 +1025,11 @@ enum Fields<'p, 'tcx> {
1025
1025
/// have not measured if it really made a difference.
1026
1026
Slice ( & ' p [ Pat < ' tcx > ] ) ,
1027
1027
Vec ( SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) ,
1028
- /// Patterns where some of the fields need to be hidden. `len ` caches the number of non-hidden
1029
- /// fields.
1028
+ /// Patterns where some of the fields need to be hidden. `kept_count ` caches the number of
1029
+ /// non-hidden fields.
1030
1030
Filtered {
1031
1031
fields : SmallVec < [ FilteredField < ' p , ' tcx > ; 2 ] > ,
1032
- len : usize ,
1032
+ kept_count : usize ,
1033
1033
} ,
1034
1034
}
1035
1035
@@ -1066,10 +1066,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1066
1066
constructor : & Constructor < ' tcx > ,
1067
1067
ty : Ty < ' tcx > ,
1068
1068
) -> Self {
1069
- debug ! ( "Fields::wildcards({:#?}, {:?})" , constructor, ty) ;
1070
1069
let wildcard_from_ty = |ty| & * cx. pattern_arena . alloc ( Pat :: wildcard_from_ty ( ty) ) ;
1071
1070
1072
- match constructor {
1071
+ let ret = match constructor {
1073
1072
Single | Variant ( _) => match ty. kind {
1074
1073
ty:: Tuple ( ref fs) => {
1075
1074
Fields :: wildcards_from_tys ( cx, fs. into_iter ( ) . map ( |ty| ty. expect_ty ( ) ) )
@@ -1093,7 +1092,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1093
1092
if has_no_hidden_fields {
1094
1093
Fields :: wildcards_from_tys ( cx, field_tys)
1095
1094
} else {
1096
- let mut len = 0 ;
1095
+ let mut kept_count = 0 ;
1097
1096
let fields = variant
1098
1097
. fields
1099
1098
. iter ( )
@@ -1110,12 +1109,12 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1110
1109
if is_uninhabited && ( !is_visible || is_non_exhaustive) {
1111
1110
FilteredField :: Hidden ( ty)
1112
1111
} else {
1113
- len += 1 ;
1112
+ kept_count += 1 ;
1114
1113
FilteredField :: Kept ( wildcard_from_ty ( ty) )
1115
1114
}
1116
1115
} )
1117
1116
. collect ( ) ;
1118
- Fields :: Filtered { fields, len }
1117
+ Fields :: Filtered { fields, kept_count }
1119
1118
}
1120
1119
}
1121
1120
}
@@ -1129,14 +1128,19 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1129
1128
_ => bug ! ( "bad slice pattern {:?} {:?}" , constructor, ty) ,
1130
1129
} ,
1131
1130
ConstantValue ( ..) | FloatRange ( ..) | IntRange ( ..) | NonExhaustive => Fields :: empty ( ) ,
1132
- }
1131
+ } ;
1132
+ debug ! ( "Fields::wildcards({:?}, {:?}) = {:#?}" , constructor, ty, ret) ;
1133
+ ret
1133
1134
}
1134
1135
1136
+ /// Returns the number of patterns from the viewpoint of match-checking, i.e. excluding hidden
1137
+ /// fields. This is what we want in most cases in this file, the only exception being
1138
+ /// conversion to/from `Pat`.
1135
1139
fn len ( & self ) -> usize {
1136
1140
match self {
1137
1141
Fields :: Slice ( pats) => pats. len ( ) ,
1138
1142
Fields :: Vec ( pats) => pats. len ( ) ,
1139
- Fields :: Filtered { len , .. } => * len ,
1143
+ Fields :: Filtered { kept_count , .. } => * kept_count ,
1140
1144
}
1141
1145
}
1142
1146
@@ -1206,7 +1210,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1206
1210
let pats: & [ _ ] = cx. pattern_arena . alloc_from_iter ( pats) ;
1207
1211
1208
1212
match self {
1209
- Fields :: Filtered { fields, len } => {
1213
+ Fields :: Filtered { fields, kept_count } => {
1210
1214
let mut pats = pats. iter ( ) ;
1211
1215
let mut fields = fields. clone ( ) ;
1212
1216
for f in & mut fields {
@@ -1215,7 +1219,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1215
1219
* p = pats. next ( ) . unwrap ( ) ;
1216
1220
}
1217
1221
}
1218
- Fields :: Filtered { fields, len : * len }
1222
+ Fields :: Filtered { fields, kept_count : * kept_count }
1219
1223
}
1220
1224
_ => Fields :: Slice ( pats) ,
1221
1225
}
@@ -1866,11 +1870,13 @@ crate fn is_useful<'p, 'tcx>(
1866
1870
return if any_is_useful { Useful ( unreachable_pats) } else { NotUseful } ;
1867
1871
}
1868
1872
1869
- let pcx = PatCtxt { ty : v. head ( ) . ty , span : v. head ( ) . span } ;
1873
+ // FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
1874
+ let ty = matrix. heads ( ) . next ( ) . map ( |r| r. ty ) . unwrap_or ( v. head ( ) . ty ) ;
1875
+ let pcx = PatCtxt { ty, span : v. head ( ) . span } ;
1870
1876
1871
1877
debug ! ( "is_useful_expand_first_col: pcx={:#?}, expanding {:#?}" , pcx, v. head( ) ) ;
1872
1878
1873
- if let Some ( constructor) = pat_constructor ( cx. tcx , cx. param_env , v. head ( ) ) {
1879
+ let ret = if let Some ( constructor) = pat_constructor ( cx. tcx , cx. param_env , v. head ( ) ) {
1874
1880
debug ! ( "is_useful - expanding constructor: {:#?}" , constructor) ;
1875
1881
split_grouped_constructors (
1876
1882
cx. tcx ,
@@ -1901,11 +1907,11 @@ crate fn is_useful<'p, 'tcx>(
1901
1907
1902
1908
let used_ctors: Vec < Constructor < ' _ > > =
1903
1909
matrix. heads ( ) . filter_map ( |p| pat_constructor ( cx. tcx , cx. param_env , p) ) . collect ( ) ;
1904
- debug ! ( "used_ctors = {:#?}" , used_ctors) ;
1910
+ debug ! ( "is_useful_used_ctors = {:#?}" , used_ctors) ;
1905
1911
// `all_ctors` are all the constructors for the given type, which
1906
1912
// should all be represented (or caught with the wild pattern `_`).
1907
1913
let all_ctors = all_constructors ( cx, pcx) ;
1908
- debug ! ( "all_ctors = {:#?}" , all_ctors) ;
1914
+ debug ! ( "is_useful_all_ctors = {:#?}" , all_ctors) ;
1909
1915
1910
1916
// `missing_ctors` is the set of constructors from the same type as the
1911
1917
// first column of `matrix` that are matched only by wildcard patterns
@@ -1920,7 +1926,7 @@ crate fn is_useful<'p, 'tcx>(
1920
1926
// can be big.
1921
1927
let missing_ctors = MissingConstructors :: new ( all_ctors, used_ctors) ;
1922
1928
1923
- debug ! ( "missing_ctors .empty()={:#?}" , missing_ctors. is_empty( ) , ) ;
1929
+ debug ! ( "is_useful_missing_ctors .empty()={:#?}" , missing_ctors. is_empty( ) , ) ;
1924
1930
1925
1931
if missing_ctors. is_empty ( ) {
1926
1932
let ( all_ctors, _) = missing_ctors. into_inner ( ) ;
@@ -1988,7 +1994,9 @@ crate fn is_useful<'p, 'tcx>(
1988
1994
usefulness. apply_missing_ctors ( cx, pcx. ty , & missing_ctors)
1989
1995
}
1990
1996
}
1991
- }
1997
+ } ;
1998
+ debug ! ( "is_useful::returns({:#?}, {:#?}) = {:?}" , matrix, v, ret) ;
1999
+ ret
1992
2000
}
1993
2001
1994
2002
/// A shorthand for the `U(S(c, P), S(c, q))` operation from the paper. I.e., `is_useful` applied
@@ -2647,7 +2655,10 @@ fn specialize_one_pattern<'p, 'tcx>(
2647
2655
2648
2656
PatKind :: Or { .. } => bug ! ( "Or-pattern should have been expanded earlier on." ) ,
2649
2657
} ;
2650
- debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , pat, ctor_wild_subpatterns, result) ;
2658
+ debug ! (
2659
+ "specialize({:#?}, {:#?}, {:#?}) = {:#?}" ,
2660
+ pat, constructor, ctor_wild_subpatterns, result
2661
+ ) ;
2651
2662
2652
2663
result
2653
2664
}
0 commit comments