]> git.proxmox.com Git - rustc.git/blob - src/librustc_mir/build/matches/util.rs
Imported Upstream version 1.5.0+dfsg1
[rustc.git] / src / librustc_mir / build / matches / util.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use build::{BlockAnd, Builder};
12 use build::matches::MatchPair;
13 use hair::*;
14 use repr::*;
15 use std::u32;
16
17 impl<'a,'tcx> Builder<'a,'tcx> {
18 pub fn field_match_pairs(&mut self,
19 lvalue: Lvalue<'tcx>,
20 subpatterns: Vec<FieldPatternRef<'tcx>>)
21 -> Vec<MatchPair<'tcx>> {
22 subpatterns.into_iter()
23 .map(|fieldpat| {
24 let lvalue = lvalue.clone().field(fieldpat.field);
25 self.match_pair(lvalue, fieldpat.pattern)
26 })
27 .collect()
28 }
29
30 pub fn match_pair(&mut self,
31 lvalue: Lvalue<'tcx>,
32 pattern: PatternRef<'tcx>)
33 -> MatchPair<'tcx> {
34 let pattern = self.hir.mirror(pattern);
35 MatchPair::new(lvalue, pattern)
36 }
37
38 /// When processing an array/slice pattern like `lv @ [x, y, ..s, z]`,
39 /// this function converts the prefix (`x`, `y`) and suffix (`z`) into
40 /// distinct match pairs:
41 ///
42 /// lv[0 of 3] @ x // see ProjectionElem::ConstantIndex (and its Debug impl)
43 /// lv[1 of 3] @ y // to explain the `[x of y]` notation
44 /// lv[-1 of 3] @ z
45 ///
46 /// If a slice like `s` is present, then the function also creates
47 /// a temporary like:
48 ///
49 /// tmp0 = lv[2..-1] // using the special Rvalue::Slice
50 ///
51 /// and creates a match pair `tmp0 @ s`
52 pub fn prefix_suffix_slice(&mut self,
53 match_pairs: &mut Vec<MatchPair<'tcx>>,
54 block: BasicBlock,
55 lvalue: Lvalue<'tcx>,
56 prefix: Vec<PatternRef<'tcx>>,
57 opt_slice: Option<PatternRef<'tcx>>,
58 suffix: Vec<PatternRef<'tcx>>)
59 -> BlockAnd<()> {
60 // If there is a `..P` pattern, create a temporary `t0` for
61 // the slice and then a match pair `t0 @ P`:
62 if let Some(slice) = opt_slice {
63 let slice = self.hir.mirror(slice);
64 let prefix_len = prefix.len();
65 let suffix_len = suffix.len();
66 let rvalue = Rvalue::Slice {
67 input: lvalue.clone(),
68 from_start: prefix_len,
69 from_end: suffix_len,
70 };
71 let temp = self.temp(slice.ty.clone()); // no need to schedule drop, temp is always copy
72 self.cfg.push_assign(block, slice.span, &temp, rvalue);
73 match_pairs.push(MatchPair::new(temp, slice));
74 }
75
76 self.prefix_suffix(match_pairs, lvalue, prefix, suffix);
77
78 block.unit()
79 }
80
81 /// Helper for `prefix_suffix_slice` which just processes the prefix and suffix.
82 fn prefix_suffix(&mut self,
83 match_pairs: &mut Vec<MatchPair<'tcx>>,
84 lvalue: Lvalue<'tcx>,
85 prefix: Vec<PatternRef<'tcx>>,
86 suffix: Vec<PatternRef<'tcx>>) {
87 let min_length = prefix.len() + suffix.len();
88 assert!(min_length < u32::MAX as usize);
89 let min_length = min_length as u32;
90
91 let prefix_pairs: Vec<_> =
92 prefix.into_iter()
93 .enumerate()
94 .map(|(idx, subpattern)| {
95 let elem = ProjectionElem::ConstantIndex {
96 offset: idx as u32,
97 min_length: min_length,
98 from_end: false,
99 };
100 let lvalue = lvalue.clone().elem(elem);
101 self.match_pair(lvalue, subpattern)
102 })
103 .collect();
104
105 let suffix_pairs: Vec<_> =
106 suffix.into_iter()
107 .rev()
108 .enumerate()
109 .map(|(idx, subpattern)| {
110 let elem = ProjectionElem::ConstantIndex {
111 offset: (idx+1) as u32,
112 min_length: min_length,
113 from_end: true,
114 };
115 let lvalue = lvalue.clone().elem(elem);
116 self.match_pair(lvalue, subpattern)
117 })
118 .collect();
119
120 match_pairs.extend(prefix_pairs.into_iter().chain(suffix_pairs));
121 }
122 }
123
124 impl<'tcx> MatchPair<'tcx> {
125 pub fn new(lvalue: Lvalue<'tcx>, pattern: Pattern<'tcx>) -> MatchPair<'tcx> {
126 MatchPair {
127 lvalue: lvalue,
128 pattern: pattern,
129 }
130 }
131 }