Skip to content

Commit 9a1a3b9

Browse files
committed
Combine two match arms in specialize().
This reduces the number of call sites for `constructor_intersects_pattern()` from two to one, which the next commit will take advantage of.
1 parent f2023ac commit 9a1a3b9

File tree

1 file changed

+68
-70
lines changed

1 file changed

+68
-70
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 68 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,13 @@ enum Constructor<'tcx> {
434434
}
435435

436436
impl<'tcx> Constructor<'tcx> {
437+
fn is_slice(&self) -> bool {
438+
match self {
439+
Slice { .. } => true,
440+
_ => false,
441+
}
442+
}
443+
437444
fn variant_index_for_adt<'a>(
438445
&self,
439446
cx: &MatchCheckCtxt<'a, 'tcx>,
@@ -1766,85 +1773,76 @@ fn specialize<'p, 'a: 'p, 'tcx>(
17661773
Some(smallvec![subpattern])
17671774
}
17681775

1769-
PatKind::Constant { value } => {
1770-
match *constructor {
1771-
Slice(..) => {
1772-
// we extract an `Option` for the pointer because slices of zero elements don't
1773-
// necessarily point to memory, they are usually just integers. The only time
1774-
// they should be pointing to memory is when they are subslices of nonzero
1775-
// slices
1776-
let (alloc, offset, n, ty) = match value.ty.kind {
1777-
ty::Array(t, n) => {
1778-
match value.val {
1779-
ConstValue::ByRef { offset, alloc, .. } => (
1780-
alloc,
1781-
offset,
1782-
n.eval_usize(cx.tcx, cx.param_env),
1783-
t,
1784-
),
1785-
_ => span_bug!(
1786-
pat.span,
1787-
"array pattern is {:?}", value,
1788-
),
1789-
}
1790-
},
1791-
ty::Slice(t) => {
1792-
match value.val {
1793-
ConstValue::Slice { data, start, end } => (
1794-
data,
1795-
Size::from_bytes(start as u64),
1796-
(end - start) as u64,
1797-
t,
1798-
),
1799-
ConstValue::ByRef { .. } => {
1800-
// FIXME(oli-obk): implement `deref` for `ConstValue`
1801-
return None;
1802-
},
1803-
_ => span_bug!(
1804-
pat.span,
1805-
"slice pattern constant must be scalar pair but is {:?}",
1806-
value,
1807-
),
1808-
}
1776+
PatKind::Constant { value } if constructor.is_slice() => {
1777+
// We extract an `Option` for the pointer because slices of zero
1778+
// elements don't necessarily point to memory, they are usually
1779+
// just integers. The only time they should be pointing to memory
1780+
// is when they are subslices of nonzero slices.
1781+
let (alloc, offset, n, ty) = match value.ty.kind {
1782+
ty::Array(t, n) => {
1783+
match value.val {
1784+
ConstValue::ByRef { offset, alloc, .. } => (
1785+
alloc,
1786+
offset,
1787+
n.eval_usize(cx.tcx, cx.param_env),
1788+
t,
1789+
),
1790+
_ => span_bug!(
1791+
pat.span,
1792+
"array pattern is {:?}", value,
1793+
),
1794+
}
1795+
},
1796+
ty::Slice(t) => {
1797+
match value.val {
1798+
ConstValue::Slice { data, start, end } => (
1799+
data,
1800+
Size::from_bytes(start as u64),
1801+
(end - start) as u64,
1802+
t,
1803+
),
1804+
ConstValue::ByRef { .. } => {
1805+
// FIXME(oli-obk): implement `deref` for `ConstValue`
1806+
return None;
18091807
},
18101808
_ => span_bug!(
18111809
pat.span,
1812-
"unexpected const-val {:?} with ctor {:?}",
1810+
"slice pattern constant must be scalar pair but is {:?}",
18131811
value,
1814-
constructor,
18151812
),
1816-
};
1817-
if wild_patterns.len() as u64 == n {
1818-
// convert a constant slice/array pattern to a list of patterns.
1819-
let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
1820-
let ptr = Pointer::new(AllocId(0), offset);
1821-
(0..n).map(|i| {
1822-
let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
1823-
let scalar = alloc.read_scalar(
1824-
&cx.tcx, ptr, layout.size,
1825-
).ok()?;
1826-
let scalar = scalar.not_undef().ok()?;
1827-
let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
1828-
let pattern = Pat {
1829-
ty,
1830-
span: pat.span,
1831-
kind: box PatKind::Constant { value },
1832-
};
1833-
Some(&*cx.pattern_arena.alloc(pattern))
1834-
}).collect()
1835-
} else {
1836-
None
18371813
}
1838-
}
1839-
_ => {
1840-
// If the constructor is a:
1841-
// Single value: add a row if the constructor equals the pattern.
1842-
// Range: add a row if the constructor contains the pattern.
1843-
constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat)
1844-
}
1814+
},
1815+
_ => span_bug!(
1816+
pat.span,
1817+
"unexpected const-val {:?} with ctor {:?}",
1818+
value,
1819+
constructor,
1820+
),
1821+
};
1822+
if wild_patterns.len() as u64 == n {
1823+
// convert a constant slice/array pattern to a list of patterns.
1824+
let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
1825+
let ptr = Pointer::new(AllocId(0), offset);
1826+
(0..n).map(|i| {
1827+
let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
1828+
let scalar = alloc.read_scalar(
1829+
&cx.tcx, ptr, layout.size,
1830+
).ok()?;
1831+
let scalar = scalar.not_undef().ok()?;
1832+
let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
1833+
let pattern = Pat {
1834+
ty,
1835+
span: pat.span,
1836+
kind: box PatKind::Constant { value },
1837+
};
1838+
Some(&*cx.pattern_arena.alloc(pattern))
1839+
}).collect()
1840+
} else {
1841+
None
18451842
}
18461843
}
18471844

1845+
PatKind::Constant { .. } |
18481846
PatKind::Range { .. } => {
18491847
// If the constructor is a:
18501848
// Single value: add a row if the pattern contains the constructor.

0 commit comments

Comments
 (0)