]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
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 | ||
92a42be0 | 11 | use build::{BlockAnd, BlockAndExtension, Builder}; |
e9174d1e SL |
12 | use build::matches::MatchPair; |
13 | use hair::*; | |
92a42be0 | 14 | use rustc::mir::repr::*; |
e9174d1e SL |
15 | use std::u32; |
16 | ||
b039eaaf | 17 | impl<'a,'tcx> Builder<'a,'tcx> { |
92a42be0 SL |
18 | pub fn field_match_pairs<'pat>(&mut self, |
19 | lvalue: Lvalue<'tcx>, | |
20 | subpatterns: &'pat [FieldPattern<'tcx>]) | |
21 | -> Vec<MatchPair<'pat, 'tcx>> { | |
22 | subpatterns.iter() | |
e9174d1e SL |
23 | .map(|fieldpat| { |
24 | let lvalue = lvalue.clone().field(fieldpat.field); | |
92a42be0 | 25 | MatchPair::new(lvalue, &fieldpat.pattern) |
e9174d1e SL |
26 | }) |
27 | .collect() | |
28 | } | |
29 | ||
e9174d1e SL |
30 | /// When processing an array/slice pattern like `lv @ [x, y, ..s, z]`, |
31 | /// this function converts the prefix (`x`, `y`) and suffix (`z`) into | |
32 | /// distinct match pairs: | |
33 | /// | |
34 | /// lv[0 of 3] @ x // see ProjectionElem::ConstantIndex (and its Debug impl) | |
35 | /// lv[1 of 3] @ y // to explain the `[x of y]` notation | |
36 | /// lv[-1 of 3] @ z | |
37 | /// | |
38 | /// If a slice like `s` is present, then the function also creates | |
39 | /// a temporary like: | |
40 | /// | |
41 | /// tmp0 = lv[2..-1] // using the special Rvalue::Slice | |
42 | /// | |
43 | /// and creates a match pair `tmp0 @ s` | |
92a42be0 SL |
44 | pub fn prefix_suffix_slice<'pat>(&mut self, |
45 | match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>, | |
46 | block: BasicBlock, | |
47 | lvalue: Lvalue<'tcx>, | |
48 | prefix: &'pat [Pattern<'tcx>], | |
49 | opt_slice: Option<&'pat Pattern<'tcx>>, | |
50 | suffix: &'pat [Pattern<'tcx>]) | |
51 | -> BlockAnd<()> { | |
e9174d1e SL |
52 | // If there is a `..P` pattern, create a temporary `t0` for |
53 | // the slice and then a match pair `t0 @ P`: | |
54 | if let Some(slice) = opt_slice { | |
e9174d1e SL |
55 | let prefix_len = prefix.len(); |
56 | let suffix_len = suffix.len(); | |
b039eaaf SL |
57 | let rvalue = Rvalue::Slice { |
58 | input: lvalue.clone(), | |
59 | from_start: prefix_len, | |
60 | from_end: suffix_len, | |
61 | }; | |
e9174d1e SL |
62 | let temp = self.temp(slice.ty.clone()); // no need to schedule drop, temp is always copy |
63 | self.cfg.push_assign(block, slice.span, &temp, rvalue); | |
64 | match_pairs.push(MatchPair::new(temp, slice)); | |
65 | } | |
66 | ||
67 | self.prefix_suffix(match_pairs, lvalue, prefix, suffix); | |
68 | ||
69 | block.unit() | |
70 | } | |
71 | ||
72 | /// Helper for `prefix_suffix_slice` which just processes the prefix and suffix. | |
92a42be0 SL |
73 | fn prefix_suffix<'pat>(&mut self, |
74 | match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>, | |
75 | lvalue: Lvalue<'tcx>, | |
76 | prefix: &'pat [Pattern<'tcx>], | |
77 | suffix: &'pat [Pattern<'tcx>]) { | |
e9174d1e SL |
78 | let min_length = prefix.len() + suffix.len(); |
79 | assert!(min_length < u32::MAX as usize); | |
80 | let min_length = min_length as u32; | |
81 | ||
82 | let prefix_pairs: Vec<_> = | |
92a42be0 | 83 | prefix.iter() |
e9174d1e SL |
84 | .enumerate() |
85 | .map(|(idx, subpattern)| { | |
86 | let elem = ProjectionElem::ConstantIndex { | |
87 | offset: idx as u32, | |
88 | min_length: min_length, | |
89 | from_end: false, | |
90 | }; | |
91 | let lvalue = lvalue.clone().elem(elem); | |
92a42be0 | 92 | MatchPair::new(lvalue, subpattern) |
e9174d1e SL |
93 | }) |
94 | .collect(); | |
95 | ||
96 | let suffix_pairs: Vec<_> = | |
92a42be0 | 97 | suffix.iter() |
e9174d1e SL |
98 | .rev() |
99 | .enumerate() | |
100 | .map(|(idx, subpattern)| { | |
101 | let elem = ProjectionElem::ConstantIndex { | |
102 | offset: (idx+1) as u32, | |
103 | min_length: min_length, | |
104 | from_end: true, | |
105 | }; | |
106 | let lvalue = lvalue.clone().elem(elem); | |
92a42be0 | 107 | MatchPair::new(lvalue, subpattern) |
e9174d1e SL |
108 | }) |
109 | .collect(); | |
110 | ||
111 | match_pairs.extend(prefix_pairs.into_iter().chain(suffix_pairs)); | |
112 | } | |
113 | } | |
114 | ||
92a42be0 SL |
115 | impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { |
116 | pub fn new(lvalue: Lvalue<'tcx>, pattern: &'pat Pattern<'tcx>) -> MatchPair<'pat, 'tcx> { | |
b039eaaf SL |
117 | MatchPair { |
118 | lvalue: lvalue, | |
119 | pattern: pattern, | |
120 | } | |
e9174d1e SL |
121 | } |
122 | } |