]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/build/matches/util.rs
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / librustc_mir / build / matches / util.rs
CommitLineData
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 11use build::{BlockAnd, BlockAndExtension, Builder};
e9174d1e
SL
12use build::matches::MatchPair;
13use hair::*;
92a42be0 14use rustc::mir::repr::*;
e9174d1e
SL
15use std::u32;
16
b039eaaf 17impl<'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
115impl<'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}