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