Skip to content

Commit 8735872

Browse files
committed
Remove the mirroring for patterns and just convert them eagerly; then,
pass around references instead of boxed values to save on clone costs.
1 parent ad3bd1b commit 8735872

File tree

13 files changed

+287
-345
lines changed

13 files changed

+287
-345
lines changed

src/librustc_mir/build/matches/mod.rs

+39-40
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
4444
// be unreachable or reachable multiple times.
4545
let var_extent = self.extent_of_innermost_scope().unwrap();
4646
for arm in &arms {
47-
self.declare_bindings(var_extent, arm.patterns[0].clone());
47+
self.declare_bindings(var_extent, &arm.patterns[0]);
4848
}
4949

5050
let mut arm_blocks = ArmBlocks {
@@ -64,18 +64,18 @@ impl<'a,'tcx> Builder<'a,'tcx> {
6464
// highest priority candidate comes last in the list. This the
6565
// reverse of the order in which candidates are written in the
6666
// source.
67-
let candidates: Vec<Candidate<'tcx>> =
67+
let candidates: Vec<_> =
6868
arms.iter()
6969
.enumerate()
7070
.rev() // highest priority comes last
7171
.flat_map(|(arm_index, arm)| {
7272
arm.patterns.iter()
7373
.rev()
74-
.map(move |pat| (arm_index, pat.clone(), arm.guard.clone()))
74+
.map(move |pat| (arm_index, pat, arm.guard.clone()))
7575
})
7676
.map(|(arm_index, pattern, guard)| {
7777
Candidate {
78-
match_pairs: vec![self.match_pair(discriminant_lvalue.clone(), pattern)],
78+
match_pairs: vec![MatchPair::new(discriminant_lvalue.clone(), pattern)],
7979
bindings: vec![],
8080
guard: guard,
8181
arm_index: arm_index,
@@ -102,12 +102,11 @@ impl<'a,'tcx> Builder<'a,'tcx> {
102102
pub fn expr_into_pattern(&mut self,
103103
mut block: BasicBlock,
104104
var_extent: CodeExtent, // lifetime of vars
105-
irrefutable_pat: PatternRef<'tcx>,
105+
irrefutable_pat: Pattern<'tcx>,
106106
initializer: ExprRef<'tcx>)
107107
-> BlockAnd<()> {
108108
// optimize the case of `let x = ...`
109-
let irrefutable_pat = self.hir.mirror(irrefutable_pat);
110-
match irrefutable_pat.kind {
109+
match *irrefutable_pat.kind {
111110
PatternKind::Binding { mutability,
112111
name,
113112
mode: BindingMode::ByValue,
@@ -128,22 +127,22 @@ impl<'a,'tcx> Builder<'a,'tcx> {
128127
let lvalue = unpack!(block = self.as_lvalue(block, initializer));
129128
self.lvalue_into_pattern(block,
130129
var_extent,
131-
PatternRef::Mirror(Box::new(irrefutable_pat)),
130+
irrefutable_pat,
132131
&lvalue)
133132
}
134133

135134
pub fn lvalue_into_pattern(&mut self,
136135
mut block: BasicBlock,
137136
var_extent: CodeExtent,
138-
irrefutable_pat: PatternRef<'tcx>,
137+
irrefutable_pat: Pattern<'tcx>,
139138
initializer: &Lvalue<'tcx>)
140139
-> BlockAnd<()> {
141140
// first, creating the bindings
142-
self.declare_bindings(var_extent, irrefutable_pat.clone());
141+
self.declare_bindings(var_extent, &irrefutable_pat);
143142

144143
// create a dummy candidate
145-
let mut candidate = Candidate::<'tcx> {
146-
match_pairs: vec![self.match_pair(initializer.clone(), irrefutable_pat.clone())],
144+
let mut candidate = Candidate {
145+
match_pairs: vec![MatchPair::new(initializer.clone(), &irrefutable_pat)],
147146
bindings: vec![],
148147
guard: None,
149148
arm_index: 0, // since we don't call `match_candidates`, this field is unused
@@ -166,29 +165,29 @@ impl<'a,'tcx> Builder<'a,'tcx> {
166165
block.unit()
167166
}
168167

169-
pub fn declare_bindings(&mut self, var_extent: CodeExtent, pattern: PatternRef<'tcx>) {
170-
let pattern = self.hir.mirror(pattern);
171-
match pattern.kind {
172-
PatternKind::Binding { mutability, name, mode: _, var, ty, subpattern } => {
168+
pub fn declare_bindings(&mut self, var_extent: CodeExtent, pattern: &Pattern<'tcx>) {
169+
match *pattern.kind {
170+
PatternKind::Binding { mutability, name, mode: _, var, ty, ref subpattern } => {
173171
self.declare_binding(var_extent, mutability, name, var, ty, pattern.span);
174-
if let Some(subpattern) = subpattern {
172+
if let Some(subpattern) = subpattern.as_ref() {
175173
self.declare_bindings(var_extent, subpattern);
176174
}
177175
}
178-
PatternKind::Array { prefix, slice, suffix } |
179-
PatternKind::Slice { prefix, slice, suffix } => {
180-
for subpattern in prefix.into_iter().chain(slice).chain(suffix) {
176+
PatternKind::Array { ref prefix, ref slice, ref suffix } |
177+
PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
178+
for subpattern in prefix.iter().chain(slice).chain(suffix) {
181179
self.declare_bindings(var_extent, subpattern);
182180
}
183181
}
184-
PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {}
185-
PatternKind::Deref { subpattern } => {
182+
PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {
183+
}
184+
PatternKind::Deref { ref subpattern } => {
186185
self.declare_bindings(var_extent, subpattern);
187186
}
188-
PatternKind::Leaf { subpatterns } |
189-
PatternKind::Variant { subpatterns, .. } => {
187+
PatternKind::Leaf { ref subpatterns } |
188+
PatternKind::Variant { ref subpatterns, .. } => {
190189
for subpattern in subpatterns {
191-
self.declare_bindings(var_extent, subpattern.pattern);
190+
self.declare_bindings(var_extent, &subpattern.pattern);
192191
}
193192
}
194193
}
@@ -202,9 +201,9 @@ struct ArmBlocks {
202201
}
203202

204203
#[derive(Clone, Debug)]
205-
struct Candidate<'tcx> {
204+
struct Candidate<'pat, 'tcx:'pat> {
206205
// all of these must be satisfied...
207-
match_pairs: Vec<MatchPair<'tcx>>,
206+
match_pairs: Vec<MatchPair<'pat, 'tcx>>,
208207

209208
// ...these bindings established...
210209
bindings: Vec<Binding<'tcx>>,
@@ -228,12 +227,12 @@ struct Binding<'tcx> {
228227
}
229228

230229
#[derive(Clone, Debug)]
231-
struct MatchPair<'tcx> {
230+
struct MatchPair<'pat, 'tcx:'pat> {
232231
// this lvalue...
233232
lvalue: Lvalue<'tcx>,
234233

235234
// ... must match this pattern.
236-
pattern: Pattern<'tcx>,
235+
pattern: &'pat Pattern<'tcx>,
237236
}
238237

239238
#[derive(Clone, Debug, PartialEq)]
@@ -280,11 +279,11 @@ struct Test<'tcx> {
280279
// Main matching algorithm
281280

282281
impl<'a,'tcx> Builder<'a,'tcx> {
283-
fn match_candidates(&mut self,
284-
span: Span,
285-
arm_blocks: &mut ArmBlocks,
286-
mut candidates: Vec<Candidate<'tcx>>,
287-
mut block: BasicBlock)
282+
fn match_candidates<'pat>(&mut self,
283+
span: Span,
284+
arm_blocks: &mut ArmBlocks,
285+
mut candidates: Vec<Candidate<'pat, 'tcx>>,
286+
mut block: BasicBlock)
288287
{
289288
debug!("matched_candidate(span={:?}, block={:?}, candidates={:?})",
290289
span, block, candidates);
@@ -347,7 +346,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
347346
let target_blocks = self.perform_test(block, &match_pair.lvalue, &test);
348347

349348
for (outcome, target_block) in target_blocks.into_iter().enumerate() {
350-
let applicable_candidates: Vec<Candidate<'tcx>> =
349+
let applicable_candidates: Vec<_> =
351350
candidates.iter()
352351
.filter_map(|candidate| {
353352
self.candidate_under_assumption(&match_pair.lvalue,
@@ -372,11 +371,11 @@ impl<'a,'tcx> Builder<'a,'tcx> {
372371
/// bindings, further tests would be a use-after-move (which would
373372
/// in turn be detected by the borrowck code that runs on the
374373
/// MIR).
375-
fn bind_and_guard_matched_candidate(&mut self,
376-
mut block: BasicBlock,
377-
arm_blocks: &mut ArmBlocks,
378-
candidate: Candidate<'tcx>)
379-
-> Option<BasicBlock> {
374+
fn bind_and_guard_matched_candidate<'pat>(&mut self,
375+
mut block: BasicBlock,
376+
arm_blocks: &mut ArmBlocks,
377+
candidate: Candidate<'pat, 'tcx>)
378+
-> Option<BasicBlock> {
380379
debug!("bind_and_guard_matched_candidate(block={:?}, candidate={:?})",
381380
block, candidate);
382381

src/librustc_mir/build/matches/simplify.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ use repr::*;
3030
use std::mem;
3131

3232
impl<'a,'tcx> Builder<'a,'tcx> {
33-
pub fn simplify_candidate(&mut self,
34-
mut block: BasicBlock,
35-
candidate: &mut Candidate<'tcx>)
36-
-> BlockAnd<()> {
33+
pub fn simplify_candidate<'pat>(&mut self,
34+
mut block: BasicBlock,
35+
candidate: &mut Candidate<'pat, 'tcx>)
36+
-> BlockAnd<()> {
3737
// repeatedly simplify match pairs until fixed point is reached
3838
loop {
3939
let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]);
@@ -60,18 +60,18 @@ impl<'a,'tcx> Builder<'a,'tcx> {
6060
/// have been pushed into the candidate. If no simplification is
6161
/// possible, Err is returned and no changes are made to
6262
/// candidate.
63-
fn simplify_match_pair(&mut self,
64-
mut block: BasicBlock,
65-
match_pair: MatchPair<'tcx>,
66-
candidate: &mut Candidate<'tcx>)
67-
-> Result<BasicBlock, MatchPair<'tcx>> {
68-
match match_pair.pattern.kind {
63+
fn simplify_match_pair<'pat>(&mut self,
64+
mut block: BasicBlock,
65+
match_pair: MatchPair<'pat, 'tcx>,
66+
candidate: &mut Candidate<'pat, 'tcx>)
67+
-> Result<BasicBlock, MatchPair<'pat, 'tcx>> {
68+
match *match_pair.pattern.kind {
6969
PatternKind::Wild(..) => {
7070
// nothing left to do
7171
Ok(block)
7272
}
7373

74-
PatternKind::Binding { name, mutability, mode, var, ty, subpattern } => {
74+
PatternKind::Binding { name, mutability, mode, var, ty, ref subpattern } => {
7575
candidate.bindings.push(Binding {
7676
name: name,
7777
mutability: mutability,
@@ -82,9 +82,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
8282
binding_mode: mode,
8383
});
8484

85-
if let Some(subpattern) = subpattern {
85+
if let Some(subpattern) = subpattern.as_ref() {
8686
// this is the `x @ P` case; have to keep matching against `P` now
87-
let subpattern = self.hir.mirror(subpattern);
8887
candidate.match_pairs.push(MatchPair::new(match_pair.lvalue, subpattern));
8988
}
9089

@@ -96,12 +95,12 @@ impl<'a,'tcx> Builder<'a,'tcx> {
9695
Err(match_pair)
9796
}
9897

99-
PatternKind::Array { prefix, slice, suffix } => {
98+
PatternKind::Array { ref prefix, ref slice, ref suffix } => {
10099
unpack!(block = self.prefix_suffix_slice(&mut candidate.match_pairs,
101100
block,
102101
match_pair.lvalue.clone(),
103102
prefix,
104-
slice,
103+
slice.as_ref(),
105104
suffix));
106105
Ok(block)
107106
}
@@ -113,16 +112,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
113112
Err(match_pair)
114113
}
115114

116-
PatternKind::Leaf { subpatterns } => {
115+
PatternKind::Leaf { ref subpatterns } => {
117116
// tuple struct, match subpats (if any)
118117
candidate.match_pairs
119118
.extend(self.field_match_pairs(match_pair.lvalue, subpatterns));
120119
Ok(block)
121120
}
122121

123-
PatternKind::Deref { subpattern } => {
122+
PatternKind::Deref { ref subpattern } => {
124123
let lvalue = match_pair.lvalue.deref();
125-
let subpattern = self.hir.mirror(subpattern);
126124
candidate.match_pairs.push(MatchPair::new(lvalue, subpattern));
127125
Ok(block)
128126
}

0 commit comments

Comments
 (0)