Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 26c05b1

Browse files
committedSep 11, 2018
Add ty::Ty to PatternKind::Range;u128 for Const in Constructor::ConstantRange
1 parent 763d91a commit 26c05b1

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>>>
@@ -1241,7 +1239,13 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt,
12411239
Some(vec![Variant(adt_def.variants[variant_index].did)])
12421240
}
12431241
PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
1244-
PatternKind::Range { lo, hi, end } => Some(vec![ConstantRange(lo, hi, end)]),
1242+
PatternKind::Range { lo, hi, ty, end } =>
1243+
Some(vec![ConstantRange(
1244+
lo.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
1245+
hi.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
1246+
ty,
1247+
end,
1248+
)]),
12451249
PatternKind::Array { .. } => match pcx.ty.sty {
12461250
ty::Array(_, length) => Some(vec![
12471251
Slice(length.unwrap_usize(cx.tcx))
@@ -1381,10 +1385,13 @@ fn slice_pat_covered_by_constructor<'tcx>(
13811385
// constructor is a range or constant with an integer type.
13821386
fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Constructor<'tcx>) -> bool {
13831387
if tcx.features().exhaustive_integer_patterns {
1384-
if let ConstantValue(value) | ConstantRange(value, _, _) = ctor {
1385-
if let ty::Char | ty::Int(_) | ty::Uint(_) = value.ty.sty {
1386-
return true;
1387-
}
1388+
let ty = match ctor {
1389+
ConstantValue(value) => value.ty,
1390+
ConstantRange(_, _, ty, _) => ty,
1391+
_ => return false,
1392+
};
1393+
if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
1394+
return true;
13881395
}
13891396
}
13901397
false
@@ -1535,7 +1542,7 @@ fn constructor_covered_by_range<'a, 'tcx>(
15351542
) -> Result<bool, ErrorReported> {
15361543
let (from, to, end, ty) = match pat.kind {
15371544
box PatternKind::Constant { value } => (value, value, RangeEnd::Included, value.ty),
1538-
box PatternKind::Range { lo, hi, end } => (lo, hi, end, lo.ty),
1545+
box PatternKind::Range { lo, hi, ty, end } => (lo, hi, end, ty),
15391546
_ => bug!("`constructor_covered_by_range` called with {:?}", pat),
15401547
};
15411548
trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
@@ -1557,17 +1564,33 @@ fn constructor_covered_by_range<'a, 'tcx>(
15571564
(end == RangeEnd::Included && to == Ordering::Equal);
15581565
Ok(some_or_ok!(cmp_from(value)) && end)
15591566
},
1560-
ConstantRange(from, to, RangeEnd::Included) => {
1561-
let to = some_or_ok!(cmp_to(to));
1567+
ConstantRange(from, to, ty, RangeEnd::Included) => {
1568+
let to = some_or_ok!(cmp_to(ty::Const::from_bits(
1569+
tcx,
1570+
to,
1571+
ty::ParamEnv::empty().and(ty),
1572+
)));
15621573
let end = (to == Ordering::Less) ||
15631574
(end == RangeEnd::Included && to == Ordering::Equal);
1564-
Ok(some_or_ok!(cmp_from(from)) && end)
1575+
Ok(some_or_ok!(cmp_from(ty::Const::from_bits(
1576+
tcx,
1577+
from,
1578+
ty::ParamEnv::empty().and(ty),
1579+
))) && end)
15651580
},
1566-
ConstantRange(from, to, RangeEnd::Excluded) => {
1567-
let to = some_or_ok!(cmp_to(to));
1581+
ConstantRange(from, to, ty, RangeEnd::Excluded) => {
1582+
let to = some_or_ok!(cmp_to(ty::Const::from_bits(
1583+
tcx,
1584+
to,
1585+
ty::ParamEnv::empty().and(ty)
1586+
)));
15681587
let end = (to == Ordering::Less) ||
15691588
(end == RangeEnd::Excluded && to == Ordering::Equal);
1570-
Ok(some_or_ok!(cmp_from(from)) && end)
1589+
Ok(some_or_ok!(cmp_from(ty::Const::from_bits(
1590+
tcx,
1591+
from,
1592+
ty::ParamEnv::empty().and(ty)))
1593+
) && end)
15711594
}
15721595
Single => Ok(true),
15731596
_ => bug!(),

‎src/librustc_mir/hair/pattern/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ pub enum PatternKind<'tcx> {
101101
Range {
102102
lo: &'tcx ty::Const<'tcx>,
103103
hi: &'tcx ty::Const<'tcx>,
104+
ty: Ty<'tcx>,
104105
end: RangeEnd,
105106
},
106107

@@ -230,7 +231,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
230231
PatternKind::Constant { value } => {
231232
fmt_const_val(f, value)
232233
}
233-
PatternKind::Range { lo, hi, end } => {
234+
PatternKind::Range { lo, hi, ty: _, end } => {
234235
fmt_const_val(f, lo)?;
235236
match end {
236237
RangeEnd::Included => write!(f, "..=")?,
@@ -359,7 +360,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
359360
);
360361
match (end, cmp) {
361362
(RangeEnd::Excluded, Some(Ordering::Less)) =>
362-
PatternKind::Range { lo, hi, end },
363+
PatternKind::Range { lo, hi, ty, end },
363364
(RangeEnd::Excluded, _) => {
364365
span_err!(
365366
self.tcx.sess,
@@ -373,7 +374,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
373374
PatternKind::Constant { value: lo }
374375
}
375376
(RangeEnd::Included, Some(Ordering::Less)) => {
376-
PatternKind::Range { lo, hi, end }
377+
PatternKind::Range { lo, hi, ty, end }
377378
}
378379
(RangeEnd::Included, _) => {
379380
let mut err = struct_span_err!(
@@ -1017,10 +1018,12 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
10171018
PatternKind::Range {
10181019
lo,
10191020
hi,
1021+
ty,
10201022
end,
10211023
} => PatternKind::Range {
10221024
lo: lo.fold_with(folder),
10231025
hi: hi.fold_with(folder),
1026+
ty: ty.fold_with(folder),
10241027
end,
10251028
},
10261029
PatternKind::Slice {

0 commit comments

Comments
 (0)
Failed to load comments.