@@ -581,7 +581,7 @@ enum Constructor<'tcx> {
581
581
582
582
// Meta-constructors
583
583
/// Ranges of literal values (`2..=5` and `2..5`).
584
- ConstantRange ( u128 , u128 , Ty < ' tcx > , RangeEnd ) ,
584
+ ConstantRange ( & ' tcx ty :: Const < ' tcx > , & ' tcx ty :: Const < ' tcx > , RangeEnd ) ,
585
585
/// Slice patterns. Captures any array constructor of length >= i+j.
586
586
VarLenSlice ( u64 , u64 ) ,
587
587
/// Wildcard metaconstructor. Captures all possible constructors for a given type.
@@ -1151,7 +1151,7 @@ impl<'tcx> Constructor<'tcx> {
1151
1151
pats : impl IntoIterator < Item = Pat < ' tcx > > ,
1152
1152
) -> SmallVec < [ Pat < ' tcx > ; 1 ] > {
1153
1153
let mut pats = pats. into_iter ( ) ;
1154
- let pat = match self {
1154
+ let pat = match * self {
1155
1155
Single | Variant ( _) => match ty. kind {
1156
1156
ty:: Adt ( ..) | ty:: Tuple ( ..) => {
1157
1157
let pats = pats
@@ -1183,7 +1183,7 @@ impl<'tcx> Constructor<'tcx> {
1183
1183
VarLenSlice ( prefix_len, _suffix_len) => match ty. kind {
1184
1184
ty:: Slice ( ty) | ty:: Array ( ty, _) => {
1185
1185
if cx. tcx . features ( ) . slice_patterns {
1186
- let prefix = pats. by_ref ( ) . take ( * prefix_len as usize ) . collect ( ) ;
1186
+ let prefix = pats. by_ref ( ) . take ( prefix_len as usize ) . collect ( ) ;
1187
1187
let suffix = pats. collect ( ) ;
1188
1188
let wild = Pat { ty, span : DUMMY_SP , kind : Box :: new ( PatKind :: Wild ) } ;
1189
1189
PatKind :: Slice { prefix, slice : Some ( wild) , suffix }
@@ -1199,13 +1199,9 @@ impl<'tcx> Constructor<'tcx> {
1199
1199
_ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
1200
1200
} ,
1201
1201
ConstantValue ( value) => PatKind :: Constant { value } ,
1202
- ConstantRange ( lo, hi, ty, end) => PatKind :: Range ( PatRange {
1203
- lo : ty:: Const :: from_bits ( cx. tcx , * lo, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
1204
- hi : ty:: Const :: from_bits ( cx. tcx , * hi, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
1205
- end : * end,
1206
- } ) ,
1202
+ ConstantRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end } ) ,
1207
1203
Wildcard => PatKind :: Wild ,
1208
- MissingConstructors ( missing_ctors) => {
1204
+ MissingConstructors ( ref missing_ctors) => {
1209
1205
// Construct for each missing constructor a "wildcard" version of this
1210
1206
// constructor, that matches everything that can be built with
1211
1207
// it. For example, if `ctor` is a `Constructor::Variant` for
@@ -1394,32 +1390,28 @@ fn all_constructors<'a, 'tcx>(
1394
1390
. map ( |v| Variant ( v. def_id ) )
1395
1391
. collect ( ) ,
1396
1392
ty:: Char => {
1393
+ let param_env = ty:: ParamEnv :: empty ( ) . and ( cx. tcx . types . char ) ;
1394
+ let to_const = |x| ty:: Const :: from_bits ( cx. tcx , x as u128 , param_env) ;
1397
1395
vec ! [
1398
1396
// The valid Unicode Scalar Value ranges.
1399
- ConstantRange (
1400
- '\u{0000}' as u128 ,
1401
- '\u{D7FF}' as u128 ,
1402
- cx. tcx. types. char ,
1403
- RangeEnd :: Included ,
1404
- ) ,
1405
- ConstantRange (
1406
- '\u{E000}' as u128 ,
1407
- '\u{10FFFF}' as u128 ,
1408
- cx. tcx. types. char ,
1409
- RangeEnd :: Included ,
1410
- ) ,
1397
+ ConstantRange ( to_const( '\u{0000}' ) , to_const( '\u{D7FF}' ) , RangeEnd :: Included ) ,
1398
+ ConstantRange ( to_const( '\u{E000}' ) , to_const( '\u{10FFFF}' ) , RangeEnd :: Included ) ,
1411
1399
]
1412
1400
}
1413
1401
ty:: Int ( ity) => {
1402
+ let param_env = ty:: ParamEnv :: empty ( ) . and ( ty) ;
1403
+ let to_const = |x| ty:: Const :: from_bits ( cx. tcx , x, param_env) ;
1414
1404
let bits = Integer :: from_attr ( & cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
1415
1405
let min = 1u128 << ( bits - 1 ) ;
1416
1406
let max = min - 1 ;
1417
- vec ! [ ConstantRange ( min, max, ty , RangeEnd :: Included ) ]
1407
+ vec ! [ ConstantRange ( to_const ( min) , to_const ( max) , RangeEnd :: Included ) ]
1418
1408
}
1419
1409
ty:: Uint ( uty) => {
1410
+ let param_env = ty:: ParamEnv :: empty ( ) . and ( ty) ;
1411
+ let to_const = |x| ty:: Const :: from_bits ( cx. tcx , x, param_env) ;
1420
1412
let size = Integer :: from_attr ( & cx. tcx , UnsignedInt ( uty) ) . size ( ) ;
1421
1413
let max = truncate ( u128:: max_value ( ) , size) ;
1422
- vec ! [ ConstantRange ( 0 , max, ty , RangeEnd :: Included ) ]
1414
+ vec ! [ ConstantRange ( to_const ( 0 ) , to_const ( max) , RangeEnd :: Included ) ]
1423
1415
}
1424
1416
_ => {
1425
1417
if cx. is_uninhabited ( ty) {
@@ -1501,11 +1493,14 @@ impl<'tcx> IntRange<'tcx> {
1501
1493
#[ inline]
1502
1494
fn from_range (
1503
1495
tcx : TyCtxt < ' tcx > ,
1504
- lo : u128 ,
1505
- hi : u128 ,
1506
- ty : Ty < ' tcx > ,
1496
+ param_env : ty :: ParamEnv < ' tcx > ,
1497
+ lo : & Const < ' tcx > ,
1498
+ hi : & Const < ' tcx > ,
1507
1499
end : & RangeEnd ,
1508
1500
) -> Option < IntRange < ' tcx > > {
1501
+ let ty = lo. ty ;
1502
+ let lo = lo. eval_bits ( tcx, param_env, lo. ty ) ;
1503
+ let hi = hi. eval_bits ( tcx, param_env, hi. ty ) ;
1509
1504
if Self :: is_integral ( ty) {
1510
1505
// Perform a shift if the underlying types are signed,
1511
1506
// which makes the interval arithmetic simpler.
@@ -1531,7 +1526,7 @@ impl<'tcx> IntRange<'tcx> {
1531
1526
// Floating-point ranges are permitted and we don't want
1532
1527
// to consider them when constructing integer ranges.
1533
1528
match ctor {
1534
- ConstantRange ( lo, hi, ty , end) => Self :: from_range ( tcx, * lo , * hi , ty , end) ,
1529
+ ConstantRange ( lo, hi, end) => Self :: from_range ( tcx, param_env , lo , hi , end) ,
1535
1530
ConstantValue ( val) => Self :: from_const ( tcx, param_env, val) ,
1536
1531
_ => None ,
1537
1532
}
@@ -1560,7 +1555,9 @@ impl<'tcx> IntRange<'tcx> {
1560
1555
let ty = ty:: ParamEnv :: empty ( ) . and ( ty) ;
1561
1556
ConstantValue ( ty:: Const :: from_bits ( tcx, lo ^ bias, ty) )
1562
1557
} else {
1563
- ConstantRange ( lo ^ bias, hi ^ bias, ty, RangeEnd :: Included )
1558
+ let param_env = ty:: ParamEnv :: empty ( ) . and ( ty) ;
1559
+ let to_const = |x| ty:: Const :: from_bits ( tcx, x, param_env) ;
1560
+ ConstantRange ( to_const ( lo ^ bias) , to_const ( hi ^ bias) , RangeEnd :: Included )
1564
1561
}
1565
1562
}
1566
1563
@@ -1811,12 +1808,7 @@ fn pat_constructors<'tcx>(
1811
1808
smallvec ! [ Variant ( adt_def. variants[ variant_index] . def_id) ]
1812
1809
}
1813
1810
PatKind :: Constant { value } => smallvec ! [ ConstantValue ( value) ] ,
1814
- PatKind :: Range ( PatRange { lo, hi, end } ) => smallvec ! [ ConstantRange (
1815
- lo. eval_bits( tcx, param_env, lo. ty) ,
1816
- hi. eval_bits( tcx, param_env, hi. ty) ,
1817
- lo. ty,
1818
- end,
1819
- ) ] ,
1811
+ PatKind :: Range ( PatRange { lo, hi, end } ) => smallvec ! [ ConstantRange ( lo, hi, end) ] ,
1820
1812
PatKind :: Array { .. } => match ty. kind {
1821
1813
ty:: Array ( _, length) => smallvec ! [ FixedLenSlice ( length. eval_usize( tcx, param_env) ) ] ,
1822
1814
_ => span_bug ! ( pat. span, "bad ty {:?} for array pattern" , ty) ,
@@ -1901,7 +1893,7 @@ fn slice_pat_covered_by_const<'tcx>(
1901
1893
fn should_treat_range_exhaustively ( tcx : TyCtxt < ' tcx > , ctor : & Constructor < ' tcx > ) -> bool {
1902
1894
let ty = match ctor {
1903
1895
ConstantValue ( value) => value. ty ,
1904
- ConstantRange ( _ , _, ty , _) => ty,
1896
+ ConstantRange ( lo , _, _) => lo . ty ,
1905
1897
_ => return false ,
1906
1898
} ;
1907
1899
if let ty:: Char | ty:: Int ( _) | ty:: Uint ( _) = ty. kind {
@@ -1921,12 +1913,7 @@ fn constructor_intersects_pattern<'p, 'tcx>(
1921
1913
if should_treat_range_exhaustively ( tcx, ctor) {
1922
1914
let range = match * pat. kind {
1923
1915
PatKind :: Constant { value } => ConstantValue ( value) ,
1924
- PatKind :: Range ( PatRange { lo, hi, end } ) => ConstantRange (
1925
- lo. eval_bits ( tcx, param_env, lo. ty ) ,
1926
- hi. eval_bits ( tcx, param_env, hi. ty ) ,
1927
- lo. ty ,
1928
- end,
1929
- ) ,
1916
+ PatKind :: Range ( PatRange { lo, hi, end } ) => ConstantRange ( lo, hi, end) ,
1930
1917
_ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , pat) ,
1931
1918
} ;
1932
1919
@@ -1942,11 +1929,12 @@ fn constructor_intersects_pattern<'p, 'tcx>(
1942
1929
// Fallback for non-ranges and ranges that involve floating-point numbers, which are not
1943
1930
// conveniently handled by `IntRange`. For these cases, the constructor may not be a range
1944
1931
// so intersection actually devolves into being covered by the pattern.
1945
- let ( from, to, end, ty ) = match * pat. kind {
1946
- PatKind :: Constant { value } => ( value, value, RangeEnd :: Included , value . ty ) ,
1947
- PatKind :: Range ( PatRange { lo, hi, end } ) => ( lo, hi, end, lo . ty ) ,
1932
+ let ( from, to, end) = match * pat. kind {
1933
+ PatKind :: Constant { value } => ( value, value, RangeEnd :: Included ) ,
1934
+ PatKind :: Range ( PatRange { lo, hi, end } ) => ( lo, hi, end) ,
1948
1935
_ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , pat) ,
1949
1936
} ;
1937
+ let ty = from. ty ;
1950
1938
trace ! ( "constructor_intersects_pattern {:#?}, {:#?}, {:#?}, {}" , ctor, from, to, ty) ;
1951
1939
let cmp_from = |c_from| compare_const_vals ( tcx, c_from, from, param_env, ty) ;
1952
1940
let cmp_to = |c_to| compare_const_vals ( tcx, c_to, to, param_env, ty) ;
@@ -1958,10 +1946,9 @@ fn constructor_intersects_pattern<'p, 'tcx>(
1958
1946
( to == Ordering :: Less ) || ( end == RangeEnd :: Included && to == Ordering :: Equal ) ;
1959
1947
( from != Ordering :: Less ) && end
1960
1948
}
1961
- ConstantRange ( from, to, ty, range_end) => {
1962
- let to = cmp_to ( ty:: Const :: from_bits ( tcx, to, ty:: ParamEnv :: empty ( ) . and ( ty) ) ) ?;
1963
- let from =
1964
- cmp_from ( ty:: Const :: from_bits ( tcx, from, ty:: ParamEnv :: empty ( ) . and ( ty) ) ) ?;
1949
+ ConstantRange ( from, to, range_end) => {
1950
+ let to = cmp_to ( to) ?;
1951
+ let from = cmp_from ( from) ?;
1965
1952
let end = ( to == Ordering :: Less ) || ( end == range_end && to == Ordering :: Equal ) ;
1966
1953
( from != Ordering :: Less ) && end
1967
1954
}
0 commit comments