]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/build/matches/util.rs
Auto merge of #57609 - matthewjasper:more-restrictive-match, r=pnkfelix
[rust.git] / src / librustc_mir / build / matches / util.rs
1 use crate::build::Builder;
2 use crate::build::matches::MatchPair;
3 use crate::hair::*;
4 use rustc::mir::*;
5 use std::u32;
6 use std::convert::TryInto;
7
8 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
9     pub fn field_match_pairs<'pat>(&mut self,
10                                    place: Place<'tcx>,
11                                    subpatterns: &'pat [FieldPattern<'tcx>])
12                                    -> Vec<MatchPair<'pat, 'tcx>> {
13         subpatterns.iter()
14                    .map(|fieldpat| {
15                        let place = place.clone().field(fieldpat.field,
16                                                        fieldpat.pattern.ty);
17                        MatchPair::new(place, &fieldpat.pattern)
18                    })
19                    .collect()
20     }
21
22     pub fn prefix_slice_suffix<'pat>(&mut self,
23                                      match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
24                                      place: &Place<'tcx>,
25                                      prefix: &'pat [Pattern<'tcx>],
26                                      opt_slice: Option<&'pat Pattern<'tcx>>,
27                                      suffix: &'pat [Pattern<'tcx>]) {
28         let min_length = prefix.len() + suffix.len();
29         let min_length = min_length.try_into().unwrap();
30
31         match_pairs.extend(
32             prefix.iter()
33                   .enumerate()
34                   .map(|(idx, subpattern)| {
35                       let elem = ProjectionElem::ConstantIndex {
36                           offset: idx as u32,
37                           min_length,
38                           from_end: false,
39                       };
40                       let place = place.clone().elem(elem);
41                       MatchPair::new(place, subpattern)
42                   })
43         );
44
45         if let Some(subslice_pat) = opt_slice {
46             let subslice = place.clone().elem(ProjectionElem::Subslice {
47                 from: prefix.len() as u32,
48                 to: suffix.len() as u32
49             });
50             match_pairs.push(MatchPair::new(subslice, subslice_pat));
51         }
52
53         match_pairs.extend(
54             suffix.iter()
55                   .rev()
56                   .enumerate()
57                   .map(|(idx, subpattern)| {
58                       let elem = ProjectionElem::ConstantIndex {
59                           offset: (idx+1) as u32,
60                           min_length,
61                           from_end: true,
62                       };
63                       let place = place.clone().elem(elem);
64                       MatchPair::new(place, subpattern)
65                   })
66         );
67     }
68 }
69
70 impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
71     pub fn new(place: Place<'tcx>, pattern: &'pat Pattern<'tcx>) -> MatchPair<'pat, 'tcx> {
72         MatchPair {
73             place,
74             pattern,
75         }
76     }
77 }