]>
git.proxmox.com Git - rustc.git/blob - 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.
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.
11 use build
::{BlockAnd, Builder}
;
12 use build
::matches
::MatchPair
;
17 impl<'a
,'tcx
> Builder
<'a
,'tcx
> {
18 pub fn field_match_pairs(&mut self,
20 subpatterns
: Vec
<FieldPatternRef
<'tcx
>>)
21 -> Vec
<MatchPair
<'tcx
>> {
22 subpatterns
.into_iter()
24 let lvalue
= lvalue
.clone().field(fieldpat
.field
);
25 self.match_pair(lvalue
, fieldpat
.pattern
)
30 pub fn match_pair(&mut self,
32 pattern
: PatternRef
<'tcx
>)
34 let pattern
= self.hir
.mirror(pattern
);
35 MatchPair
::new(lvalue
, pattern
)
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:
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
46 /// If a slice like `s` is present, then the function also creates
49 /// tmp0 = lv[2..-1] // using the special Rvalue::Slice
51 /// and creates a match pair `tmp0 @ s`
52 pub fn prefix_suffix_slice(&mut self,
53 match_pairs
: &mut Vec
<MatchPair
<'tcx
>>,
56 prefix
: Vec
<PatternRef
<'tcx
>>,
57 opt_slice
: Option
<PatternRef
<'tcx
>>,
58 suffix
: Vec
<PatternRef
<'tcx
>>)
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
,
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
));
76 self.prefix_suffix(match_pairs
, lvalue
, prefix
, suffix
);
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
>>,
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;
91 let prefix_pairs
: Vec
<_
> =
94 .map(|(idx
, subpattern
)| {
95 let elem
= ProjectionElem
::ConstantIndex
{
97 min_length
: min_length
,
100 let lvalue
= lvalue
.clone().elem(elem
);
101 self.match_pair(lvalue
, subpattern
)
105 let suffix_pairs
: Vec
<_
> =
109 .map(|(idx
, subpattern
)| {
110 let elem
= ProjectionElem
::ConstantIndex
{
111 offset
: (idx
+1) as u32,
112 min_length
: min_length
,
115 let lvalue
= lvalue
.clone().elem(elem
);
116 self.match_pair(lvalue
, subpattern
)
120 match_pairs
.extend(prefix_pairs
.into_iter().chain(suffix_pairs
));
124 impl<'tcx
> MatchPair
<'tcx
> {
125 pub fn new(lvalue
: Lvalue
<'tcx
>, pattern
: Pattern
<'tcx
>) -> MatchPair
<'tcx
> {