|
13 | 13 | //! testing a value against a constant.
|
14 | 14 |
|
15 | 15 | use crate::build::expr::as_place::PlaceBuilder;
|
16 |
| -use crate::build::matches::{Ascription, Binding, Candidate, MatchPair}; |
| 16 | +use crate::build::matches::{Ascription, Binding, Candidate, MatchPair, TestCase}; |
17 | 17 | use crate::build::Builder;
|
18 |
| -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; |
19 |
| -use rustc_middle::thir::{self, *}; |
20 |
| -use rustc_middle::ty; |
| 18 | +use rustc_middle::thir::{Pat, PatKind}; |
21 | 19 |
|
22 | 20 | use std::mem;
|
23 | 21 |
|
@@ -62,13 +60,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
62 | 60 | let mut simplified_match_pairs = Vec::new();
|
63 | 61 | // Repeatedly simplify match pairs until we're left with only unsimplifiable ones.
|
64 | 62 | loop {
|
65 |
| - for match_pair in mem::take(match_pairs) { |
66 |
| - if let Err(match_pair) = self.simplify_match_pair( |
67 |
| - match_pair, |
68 |
| - candidate_bindings, |
69 |
| - candidate_ascriptions, |
70 |
| - match_pairs, |
71 |
| - ) { |
| 63 | + for mut match_pair in mem::take(match_pairs) { |
| 64 | + if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case { |
| 65 | + if let Some(binding) = binding { |
| 66 | + candidate_bindings.push(binding); |
| 67 | + } |
| 68 | + if let Some(ascription) = ascription { |
| 69 | + candidate_ascriptions.push(ascription); |
| 70 | + } |
| 71 | + // Simplifiable pattern; we replace it with its subpairs and simplify further. |
| 72 | + match_pairs.append(&mut match_pair.subpairs); |
| 73 | + } else { |
| 74 | + // Unsimplifiable pattern; we recursively simplify its subpairs and don't |
| 75 | + // process it further. |
| 76 | + self.simplify_match_pairs( |
| 77 | + &mut match_pair.subpairs, |
| 78 | + candidate_bindings, |
| 79 | + candidate_ascriptions, |
| 80 | + ); |
72 | 81 | simplified_match_pairs.push(match_pair);
|
73 | 82 | }
|
74 | 83 | }
|
@@ -117,133 +126,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
117 | 126 | })
|
118 | 127 | .collect()
|
119 | 128 | }
|
120 |
| - |
121 |
| - /// Tries to simplify `match_pair`, returning `Ok(())` if successful. If successful, new match |
122 |
| - /// pairs and bindings will have been pushed into the respective `Vec`s. If no simplification is |
123 |
| - /// possible, `Err` is returned. |
124 |
| - fn simplify_match_pair<'pat>( |
125 |
| - &mut self, |
126 |
| - mut match_pair: MatchPair<'pat, 'tcx>, |
127 |
| - bindings: &mut Vec<Binding<'tcx>>, |
128 |
| - ascriptions: &mut Vec<Ascription<'tcx>>, |
129 |
| - match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>, |
130 |
| - ) -> Result<(), MatchPair<'pat, 'tcx>> { |
131 |
| - match match_pair.pattern.kind { |
132 |
| - PatKind::Leaf { .. } |
133 |
| - | PatKind::Deref { .. } |
134 |
| - | PatKind::Array { .. } |
135 |
| - | PatKind::Never |
136 |
| - | PatKind::Wild |
137 |
| - | PatKind::Error(_) => {} |
138 |
| - |
139 |
| - PatKind::AscribeUserType { |
140 |
| - ascription: thir::Ascription { ref annotation, variance }, |
141 |
| - .. |
142 |
| - } => { |
143 |
| - // Apply the type ascription to the value at `match_pair.place` |
144 |
| - if let Some(source) = match_pair.place.try_to_place(self) { |
145 |
| - ascriptions.push(Ascription { |
146 |
| - annotation: annotation.clone(), |
147 |
| - source, |
148 |
| - variance, |
149 |
| - }); |
150 |
| - } |
151 |
| - } |
152 |
| - |
153 |
| - PatKind::Binding { |
154 |
| - name: _, |
155 |
| - mutability: _, |
156 |
| - mode, |
157 |
| - var, |
158 |
| - ty: _, |
159 |
| - subpattern: _, |
160 |
| - is_primary: _, |
161 |
| - } => { |
162 |
| - if let Some(source) = match_pair.place.try_to_place(self) { |
163 |
| - bindings.push(Binding { |
164 |
| - span: match_pair.pattern.span, |
165 |
| - source, |
166 |
| - var_id: var, |
167 |
| - binding_mode: mode, |
168 |
| - }); |
169 |
| - } |
170 |
| - } |
171 |
| - |
172 |
| - PatKind::InlineConstant { subpattern: ref pattern, def } => { |
173 |
| - // Apply a type ascription for the inline constant to the value at `match_pair.place` |
174 |
| - if let Some(source) = match_pair.place.try_to_place(self) { |
175 |
| - let span = match_pair.pattern.span; |
176 |
| - let parent_id = self.tcx.typeck_root_def_id(self.def_id.to_def_id()); |
177 |
| - let args = ty::InlineConstArgs::new( |
178 |
| - self.tcx, |
179 |
| - ty::InlineConstArgsParts { |
180 |
| - parent_args: ty::GenericArgs::identity_for_item(self.tcx, parent_id), |
181 |
| - ty: self.infcx.next_ty_var(TypeVariableOrigin { |
182 |
| - kind: TypeVariableOriginKind::MiscVariable, |
183 |
| - span, |
184 |
| - }), |
185 |
| - }, |
186 |
| - ) |
187 |
| - .args; |
188 |
| - let user_ty = |
189 |
| - self.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf( |
190 |
| - def.to_def_id(), |
191 |
| - ty::UserArgs { args, user_self_ty: None }, |
192 |
| - )); |
193 |
| - let annotation = ty::CanonicalUserTypeAnnotation { |
194 |
| - inferred_ty: pattern.ty, |
195 |
| - span, |
196 |
| - user_ty: Box::new(user_ty), |
197 |
| - }; |
198 |
| - ascriptions.push(Ascription { |
199 |
| - annotation, |
200 |
| - source, |
201 |
| - variance: ty::Contravariant, |
202 |
| - }); |
203 |
| - } |
204 |
| - } |
205 |
| - |
206 |
| - PatKind::Constant { .. } => { |
207 |
| - // FIXME normalize patterns when possible |
208 |
| - return Err(match_pair); |
209 |
| - } |
210 |
| - |
211 |
| - PatKind::Range(ref range) => { |
212 |
| - if range.is_full_range(self.tcx) != Some(true) { |
213 |
| - return Err(match_pair); |
214 |
| - } |
215 |
| - } |
216 |
| - |
217 |
| - PatKind::Slice { ref prefix, ref slice, ref suffix } => { |
218 |
| - if !(prefix.is_empty() && slice.is_some() && suffix.is_empty()) { |
219 |
| - self.simplify_match_pairs(&mut match_pair.subpairs, bindings, ascriptions); |
220 |
| - return Err(match_pair); |
221 |
| - } |
222 |
| - } |
223 |
| - |
224 |
| - PatKind::Variant { adt_def, args, variant_index, subpatterns: _ } => { |
225 |
| - let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { |
226 |
| - i == variant_index || { |
227 |
| - (self.tcx.features().exhaustive_patterns |
228 |
| - || self.tcx.features().min_exhaustive_patterns) |
229 |
| - && !v |
230 |
| - .inhabited_predicate(self.tcx, adt_def) |
231 |
| - .instantiate(self.tcx, args) |
232 |
| - .apply_ignore_module(self.tcx, self.param_env) |
233 |
| - } |
234 |
| - }) && (adt_def.did().is_local() |
235 |
| - || !adt_def.is_variant_list_non_exhaustive()); |
236 |
| - if !irrefutable { |
237 |
| - self.simplify_match_pairs(&mut match_pair.subpairs, bindings, ascriptions); |
238 |
| - return Err(match_pair); |
239 |
| - } |
240 |
| - } |
241 |
| - |
242 |
| - PatKind::Or { .. } => return Err(match_pair), |
243 |
| - } |
244 |
| - |
245 |
| - // Simplifiable pattern; we replace it with its subpairs. |
246 |
| - match_pairs.append(&mut match_pair.subpairs); |
247 |
| - Ok(()) |
248 |
| - } |
249 | 129 | }
|
0 commit comments