|
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