Skip to content

Commit a2b991b

Browse files
committed
Auto merge of #51159 - pacman82:master, r=oli-obk
First step towards `u128` instead of `Const` in `PatternKind::Range` This PR accomplishes two things: * It adds `ty::Ty` to `PatternKind::Range`. The extra type information will make it easier to remove it from the `hi` and `lo` members. * It exchanges `Const` for `u128` in `Constructor::ConstantRange`.
2 parents 5806389 + 26c05b1 commit a2b991b

File tree

3 files changed

+86
-59
lines changed

3 files changed

+86
-59
lines changed

src/librustc_mir/build/matches/test.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
7070
}
7171
}
7272

73-
PatternKind::Range { lo, hi, end } => {
73+
PatternKind::Range { lo, hi, ty, end } => {
74+
assert!(ty == match_pair.pattern.ty);
7475
Test {
7576
span: match_pair.pattern.span,
7677
kind: TestKind::Range {
7778
lo,
7879
hi,
79-
ty: match_pair.pattern.ty.clone(),
80+
ty,
8081
end,
8182
},
8283
}

src/librustc_mir/hair/pattern/_match.rs

+77-54
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ pub enum Constructor<'tcx> {
416416
/// Literal values.
417417
ConstantValue(&'tcx ty::Const<'tcx>),
418418
/// Ranges of literal values (`2...5` and `2..5`).
419-
ConstantRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd),
419+
ConstantRange(u128, u128, Ty<'tcx>, RangeEnd),
420420
/// Array patterns of length n.
421421
Slice(u64),
422422
}
@@ -588,7 +588,12 @@ impl<'tcx> Witness<'tcx> {
588588
_ => {
589589
match *ctor {
590590
ConstantValue(value) => PatternKind::Constant { value },
591-
ConstantRange(lo, hi, end) => PatternKind::Range { lo, hi, end },
591+
ConstantRange(lo, hi, ty, end) => PatternKind::Range {
592+
lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
593+
hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
594+
ty,
595+
end,
596+
},
592597
_ => PatternKind::Wild,
593598
}
594599
}
@@ -648,34 +653,32 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
648653
.collect()
649654
}
650655
ty::Char if exhaustive_integer_patterns => {
651-
let endpoint = |c: char| {
652-
let ty = ty::ParamEnv::empty().and(cx.tcx.types.char);
653-
ty::Const::from_bits(cx.tcx, c as u128, ty)
654-
};
655656
vec![
656657
// The valid Unicode Scalar Value ranges.
657-
ConstantRange(endpoint('\u{0000}'), endpoint('\u{D7FF}'), RangeEnd::Included),
658-
ConstantRange(endpoint('\u{E000}'), endpoint('\u{10FFFF}'), RangeEnd::Included),
658+
ConstantRange('\u{0000}' as u128,
659+
'\u{D7FF}' as u128,
660+
cx.tcx.types.char,
661+
RangeEnd::Included
662+
),
663+
ConstantRange('\u{E000}' as u128,
664+
'\u{10FFFF}' as u128,
665+
cx.tcx.types.char,
666+
RangeEnd::Included
667+
),
659668
]
660669
}
661670
ty::Int(ity) if exhaustive_integer_patterns => {
662671
// FIXME(49937): refactor these bit manipulations into interpret.
663672
let bits = Integer::from_attr(cx.tcx, SignedInt(ity)).size().bits() as u128;
664673
let min = 1u128 << (bits - 1);
665674
let max = (1u128 << (bits - 1)) - 1;
666-
let ty = ty::ParamEnv::empty().and(pcx.ty);
667-
vec![ConstantRange(ty::Const::from_bits(cx.tcx, min as u128, ty),
668-
ty::Const::from_bits(cx.tcx, max as u128, ty),
669-
RangeEnd::Included)]
675+
vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
670676
}
671677
ty::Uint(uty) if exhaustive_integer_patterns => {
672678
// FIXME(49937): refactor these bit manipulations into interpret.
673679
let bits = Integer::from_attr(cx.tcx, UnsignedInt(uty)).size().bits() as u128;
674680
let max = !0u128 >> (128 - bits);
675-
let ty = ty::ParamEnv::empty().and(pcx.ty);
676-
vec![ConstantRange(ty::Const::from_bits(cx.tcx, 0, ty),
677-
ty::Const::from_bits(cx.tcx, max, ty),
678-
RangeEnd::Included)]
681+
vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)]
679682
}
680683
_ => {
681684
if cx.is_uninhabited(pcx.ty) {
@@ -811,26 +814,18 @@ impl<'tcx> IntRange<'tcx> {
811814
ctor: &Constructor<'tcx>)
812815
-> Option<IntRange<'tcx>> {
813816
match ctor {
814-
ConstantRange(lo, hi, end) => {
815-
assert_eq!(lo.ty, hi.ty);
816-
let ty = lo.ty;
817-
let env_ty = ty::ParamEnv::empty().and(ty);
818-
if let Some(lo) = lo.assert_bits(tcx, env_ty) {
819-
if let Some(hi) = hi.assert_bits(tcx, env_ty) {
820-
// Perform a shift if the underlying types are signed,
821-
// which makes the interval arithmetic simpler.
822-
let bias = IntRange::signed_bias(tcx, ty);
823-
let (lo, hi) = (lo ^ bias, hi ^ bias);
824-
// Make sure the interval is well-formed.
825-
return if lo > hi || lo == hi && *end == RangeEnd::Excluded {
826-
None
827-
} else {
828-
let offset = (*end == RangeEnd::Excluded) as u128;
829-
Some(IntRange { range: lo..=(hi - offset), ty })
830-
};
831-
}
817+
ConstantRange(lo, hi, ty, end) => {
818+
// Perform a shift if the underlying types are signed,
819+
// which makes the interval arithmetic simpler.
820+
let bias = IntRange::signed_bias(tcx, ty);
821+
let (lo, hi) = (lo ^ bias, hi ^ bias);
822+
// Make sure the interval is well-formed.
823+
if lo > hi || lo == hi && *end == RangeEnd::Excluded {
824+
None
825+
} else {
826+
let offset = (*end == RangeEnd::Excluded) as u128;
827+
Some(IntRange { range: lo..=(hi - offset), ty })
832828
}
833-
None
834829
}
835830
ConstantValue(val) => {
836831
let ty = val.ty;
@@ -853,7 +848,12 @@ impl<'tcx> IntRange<'tcx> {
853848
-> Option<IntRange<'tcx>> {
854849
Self::from_ctor(tcx, &match pat.kind {
855850
box PatternKind::Constant { value } => ConstantValue(value),
856-
box PatternKind::Range { lo, hi, end } => ConstantRange(lo, hi, end),
851+
box PatternKind::Range { lo, hi, ty, end } => ConstantRange(
852+
lo.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
853+
hi.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
854+
ty,
855+
end,
856+
),
857857
_ => return None,
858858
})
859859
}
@@ -876,14 +876,12 @@ impl<'tcx> IntRange<'tcx> {
876876
r: RangeInclusive<u128>,
877877
) -> Constructor<'tcx> {
878878
let bias = IntRange::signed_bias(tcx, ty);
879-
let ty = ty::ParamEnv::empty().and(ty);
880879
let (lo, hi) = r.into_inner();
881880
if lo == hi {
881+
let ty = ty::ParamEnv::empty().and(ty);
882882
ConstantValue(ty::Const::from_bits(tcx, lo ^ bias, ty))
883883
} else {
884-
ConstantRange(ty::Const::from_bits(tcx, lo ^ bias, ty),
885-
ty::Const::from_bits(tcx, hi ^ bias, ty),
886-
RangeEnd::Included)
884+
ConstantRange(lo ^ bias, hi ^ bias, ty, RangeEnd::Included)
887885
}
888886
}
889887

@@ -1228,8 +1226,8 @@ fn is_useful_specialized<'p, 'a:'p, 'tcx: 'a>(
12281226
/// Slice patterns, however, can match slices of different lengths. For instance,
12291227
/// `[a, b, ..tail]` can match a slice of length 2, 3, 4 and so on.
12301228
///
1231-
/// Returns `None` in case of a catch-all, which can't be specialized.
1232-
fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt,
1229+
/// Returns None in case of a catch-all, which can't be specialized.
1230+
fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
12331231
pat: &Pattern<'tcx>,
12341232
pcx: PatternContext)
12351233
-> Option<Vec<Constructor<'tcx>>>
@@ -1243,7 +1241,13 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt,
12431241
Some(vec![Variant(adt_def.variants[variant_index].did)])
12441242
}
12451243
PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
1246-
PatternKind::Range { lo, hi, end } => Some(vec![ConstantRange(lo, hi, end)]),
1244+
PatternKind::Range { lo, hi, ty, end } =>
1245+
Some(vec![ConstantRange(
1246+
lo.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
1247+
hi.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
1248+
ty,
1249+
end,
1250+
)]),
12471251
PatternKind::Array { .. } => match pcx.ty.sty {
12481252
ty::Array(_, length) => Some(vec![
12491253
Slice(length.unwrap_usize(cx.tcx))
@@ -1383,10 +1387,13 @@ fn slice_pat_covered_by_constructor<'tcx>(
13831387
// constructor is a range or constant with an integer type.
13841388
fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Constructor<'tcx>) -> bool {
13851389
if tcx.features().exhaustive_integer_patterns {
1386-
if let ConstantValue(value) | ConstantRange(value, _, _) = ctor {
1387-
if let ty::Char | ty::Int(_) | ty::Uint(_) = value.ty.sty {
1388-
return true;
1389-
}
1390+
let ty = match ctor {
1391+
ConstantValue(value) => value.ty,
1392+
ConstantRange(_, _, ty, _) => ty,
1393+
_ => return false,
1394+
};
1395+
if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
1396+
return true;
13901397
}
13911398
}
13921399
false
@@ -1537,7 +1544,7 @@ fn constructor_covered_by_range<'a, 'tcx>(
15371544
) -> Result<bool, ErrorReported> {
15381545
let (from, to, end, ty) = match pat.kind {
15391546
box PatternKind::Constant { value } => (value, value, RangeEnd::Included, value.ty),
1540-
box PatternKind::Range { lo, hi, end } => (lo, hi, end, lo.ty),
1547+
box PatternKind::Range { lo, hi, ty, end } => (lo, hi, end, ty),
15411548
_ => bug!("`constructor_covered_by_range` called with {:?}", pat),
15421549
};
15431550
trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
@@ -1559,17 +1566,33 @@ fn constructor_covered_by_range<'a, 'tcx>(
15591566
(end == RangeEnd::Included && to == Ordering::Equal);
15601567
Ok(some_or_ok!(cmp_from(value)) && end)
15611568
},
1562-
ConstantRange(from, to, RangeEnd::Included) => {
1563-
let to = some_or_ok!(cmp_to(to));
1569+
ConstantRange(from, to, ty, RangeEnd::Included) => {
1570+
let to = some_or_ok!(cmp_to(ty::Const::from_bits(
1571+
tcx,
1572+
to,
1573+
ty::ParamEnv::empty().and(ty),
1574+
)));
15641575
let end = (to == Ordering::Less) ||
15651576
(end == RangeEnd::Included && to == Ordering::Equal);
1566-
Ok(some_or_ok!(cmp_from(from)) && end)
1577+
Ok(some_or_ok!(cmp_from(ty::Const::from_bits(
1578+
tcx,
1579+
from,
1580+
ty::ParamEnv::empty().and(ty),
1581+
))) && end)
15671582
},
1568-
ConstantRange(from, to, RangeEnd::Excluded) => {
1569-
let to = some_or_ok!(cmp_to(to));
1583+
ConstantRange(from, to, ty, RangeEnd::Excluded) => {
1584+
let to = some_or_ok!(cmp_to(ty::Const::from_bits(
1585+
tcx,
1586+
to,
1587+
ty::ParamEnv::empty().and(ty)
1588+
)));
15701589
let end = (to == Ordering::Less) ||
15711590
(end == RangeEnd::Excluded && to == Ordering::Equal);
1572-
Ok(some_or_ok!(cmp_from(from)) && end)
1591+
Ok(some_or_ok!(cmp_from(ty::Const::from_bits(
1592+
tcx,
1593+
from,
1594+
ty::ParamEnv::empty().and(ty)))
1595+
) && end)
15731596
}
15741597
Single => Ok(true),
15751598
_ => bug!(),

src/librustc_mir/hair/pattern/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pub enum PatternKind<'tcx> {
106106
Range {
107107
lo: &'tcx ty::Const<'tcx>,
108108
hi: &'tcx ty::Const<'tcx>,
109+
ty: Ty<'tcx>,
109110
end: RangeEnd,
110111
},
111112

@@ -237,7 +238,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
237238
PatternKind::Constant { value } => {
238239
fmt_const_val(f, value)
239240
}
240-
PatternKind::Range { lo, hi, end } => {
241+
PatternKind::Range { lo, hi, ty: _, end } => {
241242
fmt_const_val(f, lo)?;
242243
match end {
243244
RangeEnd::Included => write!(f, "..=")?,
@@ -366,7 +367,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
366367
);
367368
match (end, cmp) {
368369
(RangeEnd::Excluded, Some(Ordering::Less)) =>
369-
PatternKind::Range { lo, hi, end },
370+
PatternKind::Range { lo, hi, ty, end },
370371
(RangeEnd::Excluded, _) => {
371372
span_err!(
372373
self.tcx.sess,
@@ -380,7 +381,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
380381
PatternKind::Constant { value: lo }
381382
}
382383
(RangeEnd::Included, Some(Ordering::Less)) => {
383-
PatternKind::Range { lo, hi, end }
384+
PatternKind::Range { lo, hi, ty, end }
384385
}
385386
(RangeEnd::Included, _) => {
386387
let mut err = struct_span_err!(
@@ -1031,10 +1032,12 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
10311032
PatternKind::Range {
10321033
lo,
10331034
hi,
1035+
ty,
10341036
end,
10351037
} => PatternKind::Range {
10361038
lo: lo.fold_with(folder),
10371039
hi: hi.fold_with(folder),
1040+
ty: ty.fold_with(folder),
10381041
end,
10391042
},
10401043
PatternKind::Slice {

0 commit comments

Comments
 (0)