]>
Commit | Line | Data |
---|---|---|
c30ab7b3 SL |
1 | // Copyright 2016 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 | ||
11 | use eval; | |
12 | ||
13 | use rustc::middle::const_val::ConstVal; | |
14 | use rustc::mir::{Field, BorrowKind, Mutability}; | |
15 | use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region}; | |
16 | use rustc::hir::{self, PatKind}; | |
17 | use rustc::hir::def::Def; | |
18 | use rustc::hir::def_id::DefId; | |
19 | use rustc::hir::pat_util::EnumerateAndAdjustIterator; | |
20 | ||
21 | use rustc_data_structures::indexed_vec::Idx; | |
22 | ||
23 | use syntax::ast; | |
24 | use syntax::ptr::P; | |
25 | use syntax_pos::Span; | |
26 | ||
27 | #[derive(Clone, Debug)] | |
28 | pub enum PatternError { | |
29 | StaticInPattern(Span), | |
30 | BadConstInPattern(Span, DefId), | |
31 | ConstEval(eval::ConstEvalErr), | |
32 | } | |
33 | ||
34 | #[derive(Copy, Clone, Debug)] | |
35 | pub enum BindingMode<'tcx> { | |
36 | ByValue, | |
37 | ByRef(&'tcx Region, BorrowKind), | |
38 | } | |
39 | ||
40 | #[derive(Clone, Debug)] | |
41 | pub struct FieldPattern<'tcx> { | |
42 | pub field: Field, | |
43 | pub pattern: Pattern<'tcx>, | |
44 | } | |
45 | ||
46 | #[derive(Clone, Debug)] | |
47 | pub struct Pattern<'tcx> { | |
48 | pub ty: Ty<'tcx>, | |
49 | pub span: Span, | |
50 | pub kind: Box<PatternKind<'tcx>>, | |
51 | } | |
52 | ||
53 | #[derive(Clone, Debug)] | |
54 | pub enum PatternKind<'tcx> { | |
55 | Wild, | |
56 | ||
57 | /// x, ref x, x @ P, etc | |
58 | Binding { | |
59 | mutability: Mutability, | |
60 | name: ast::Name, | |
61 | mode: BindingMode<'tcx>, | |
62 | var: ast::NodeId, | |
63 | ty: Ty<'tcx>, | |
64 | subpattern: Option<Pattern<'tcx>>, | |
65 | }, | |
66 | ||
67 | /// Foo(...) or Foo{...} or Foo, where `Foo` is a variant name from an adt with >1 variants | |
68 | Variant { | |
476ff2be | 69 | adt_def: &'tcx AdtDef, |
c30ab7b3 SL |
70 | variant_index: usize, |
71 | subpatterns: Vec<FieldPattern<'tcx>>, | |
72 | }, | |
73 | ||
74 | /// (...), Foo(...), Foo{...}, or Foo, where `Foo` is a variant name from an adt with 1 variant | |
75 | Leaf { | |
76 | subpatterns: Vec<FieldPattern<'tcx>>, | |
77 | }, | |
78 | ||
79 | /// box P, &P, &mut P, etc | |
80 | Deref { | |
81 | subpattern: Pattern<'tcx>, | |
82 | }, | |
83 | ||
84 | Constant { | |
85 | value: ConstVal, | |
86 | }, | |
87 | ||
88 | Range { | |
89 | lo: ConstVal, | |
90 | hi: ConstVal, | |
91 | }, | |
92 | ||
93 | /// matches against a slice, checking the length and extracting elements | |
94 | Slice { | |
95 | prefix: Vec<Pattern<'tcx>>, | |
96 | slice: Option<Pattern<'tcx>>, | |
97 | suffix: Vec<Pattern<'tcx>>, | |
98 | }, | |
99 | ||
100 | /// fixed match against an array, irrefutable | |
101 | Array { | |
102 | prefix: Vec<Pattern<'tcx>>, | |
103 | slice: Option<Pattern<'tcx>>, | |
104 | suffix: Vec<Pattern<'tcx>>, | |
105 | }, | |
106 | } | |
107 | ||
108 | pub struct PatternContext<'a, 'gcx: 'tcx, 'tcx: 'a> { | |
109 | pub tcx: TyCtxt<'a, 'gcx, 'tcx>, | |
110 | pub errors: Vec<PatternError>, | |
111 | } | |
112 | ||
113 | impl<'a, 'gcx, 'tcx> Pattern<'tcx> { | |
114 | pub fn from_hir(tcx: TyCtxt<'a, 'gcx, 'tcx>, pat: &hir::Pat) -> Self { | |
115 | let mut pcx = PatternContext::new(tcx); | |
116 | let result = pcx.lower_pattern(pat); | |
117 | if !pcx.errors.is_empty() { | |
118 | span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors) | |
119 | } | |
120 | debug!("Pattern::from_hir({:?}) = {:?}", pat, result); | |
121 | result | |
122 | } | |
123 | } | |
124 | ||
125 | impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { | |
126 | pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { | |
127 | PatternContext { tcx: tcx, errors: vec![] } | |
128 | } | |
129 | ||
130 | pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> { | |
131 | let mut ty = self.tcx.tables().node_id_to_type(pat.id); | |
132 | ||
133 | let kind = match pat.node { | |
134 | PatKind::Wild => PatternKind::Wild, | |
135 | ||
136 | PatKind::Lit(ref value) => { | |
137 | match eval::eval_const_expr_checked(self.tcx.global_tcx(), value) { | |
138 | Ok(value) => { | |
139 | PatternKind::Constant { value: value } | |
140 | } | |
141 | Err(e) => { | |
142 | self.errors.push(PatternError::ConstEval(e)); | |
143 | PatternKind::Wild | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | PatKind::Range(ref lo, ref hi) => { | |
149 | let r_lo = eval::eval_const_expr_checked(self.tcx.global_tcx(), lo); | |
150 | if let Err(ref e_lo) = r_lo { | |
151 | self.errors.push(PatternError::ConstEval(e_lo.clone())); | |
152 | } | |
153 | ||
154 | let r_hi = eval::eval_const_expr_checked(self.tcx.global_tcx(), hi); | |
155 | if let Err(ref e_hi) = r_hi { | |
156 | self.errors.push(PatternError::ConstEval(e_hi.clone())); | |
157 | } | |
158 | ||
159 | if let (Ok(lo), Ok(hi)) = (r_lo, r_hi) { | |
160 | PatternKind::Range { lo: lo, hi: hi } | |
161 | } else { | |
162 | PatternKind::Wild | |
163 | } | |
164 | } | |
165 | ||
476ff2be SL |
166 | PatKind::Path(ref qpath) => { |
167 | let def = self.tcx.tables().qpath_def(qpath, pat.id); | |
168 | match def { | |
c30ab7b3 SL |
169 | Def::Const(def_id) | Def::AssociatedConst(def_id) => { |
170 | let tcx = self.tcx.global_tcx(); | |
171 | let substs = tcx.tables().node_id_item_substs(pat.id) | |
172 | .unwrap_or_else(|| tcx.intern_substs(&[])); | |
173 | match eval::lookup_const_by_id(tcx, def_id, Some(substs)) { | |
174 | Some((const_expr, _const_ty)) => { | |
175 | match eval::const_expr_to_pat( | |
176 | tcx, const_expr, pat.id, pat.span) | |
177 | { | |
178 | Ok(pat) => return self.lower_pattern(&pat), | |
179 | Err(_) => { | |
180 | self.errors.push(PatternError::BadConstInPattern( | |
181 | pat.span, def_id)); | |
182 | PatternKind::Wild | |
183 | } | |
184 | } | |
185 | } | |
186 | None => { | |
187 | self.errors.push(PatternError::StaticInPattern(pat.span)); | |
188 | PatternKind::Wild | |
189 | } | |
190 | } | |
191 | } | |
476ff2be | 192 | _ => self.lower_variant_or_leaf(def, vec![]) |
c30ab7b3 SL |
193 | } |
194 | } | |
195 | ||
196 | PatKind::Ref(ref subpattern, _) | | |
197 | PatKind::Box(ref subpattern) => { | |
198 | PatternKind::Deref { subpattern: self.lower_pattern(subpattern) } | |
199 | } | |
200 | ||
201 | PatKind::Slice(ref prefix, ref slice, ref suffix) => { | |
202 | let ty = self.tcx.tables().node_id_to_type(pat.id); | |
203 | match ty.sty { | |
204 | ty::TyRef(_, mt) => | |
205 | PatternKind::Deref { | |
206 | subpattern: Pattern { | |
207 | ty: mt.ty, | |
208 | span: pat.span, | |
209 | kind: Box::new(self.slice_or_array_pattern( | |
210 | pat.span, mt.ty, prefix, slice, suffix)) | |
211 | }, | |
212 | }, | |
213 | ||
214 | ty::TySlice(..) | | |
215 | ty::TyArray(..) => | |
216 | self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix), | |
217 | ||
218 | ref sty => | |
219 | span_bug!( | |
220 | pat.span, | |
221 | "unexpanded type for vector pattern: {:?}", | |
222 | sty), | |
223 | } | |
224 | } | |
225 | ||
226 | PatKind::Tuple(ref subpatterns, ddpos) => { | |
227 | let ty = self.tcx.tables().node_id_to_type(pat.id); | |
228 | match ty.sty { | |
229 | ty::TyTuple(ref tys) => { | |
230 | let subpatterns = | |
231 | subpatterns.iter() | |
232 | .enumerate_and_adjust(tys.len(), ddpos) | |
233 | .map(|(i, subpattern)| FieldPattern { | |
234 | field: Field::new(i), | |
235 | pattern: self.lower_pattern(subpattern) | |
236 | }) | |
237 | .collect(); | |
238 | ||
239 | PatternKind::Leaf { subpatterns: subpatterns } | |
240 | } | |
241 | ||
242 | ref sty => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", sty), | |
243 | } | |
244 | } | |
245 | ||
476ff2be | 246 | PatKind::Binding(bm, def_id, ref ident, ref sub) => { |
c30ab7b3 SL |
247 | let id = self.tcx.map.as_local_node_id(def_id).unwrap(); |
248 | let var_ty = self.tcx.tables().node_id_to_type(pat.id); | |
249 | let region = match var_ty.sty { | |
250 | ty::TyRef(r, _) => Some(r), | |
251 | _ => None, | |
252 | }; | |
253 | let (mutability, mode) = match bm { | |
254 | hir::BindByValue(hir::MutMutable) => | |
255 | (Mutability::Mut, BindingMode::ByValue), | |
256 | hir::BindByValue(hir::MutImmutable) => | |
257 | (Mutability::Not, BindingMode::ByValue), | |
258 | hir::BindByRef(hir::MutMutable) => | |
259 | (Mutability::Not, BindingMode::ByRef(region.unwrap(), BorrowKind::Mut)), | |
260 | hir::BindByRef(hir::MutImmutable) => | |
261 | (Mutability::Not, BindingMode::ByRef(region.unwrap(), BorrowKind::Shared)), | |
262 | }; | |
263 | ||
264 | // A ref x pattern is the same node used for x, and as such it has | |
265 | // x's type, which is &T, where we want T (the type being matched). | |
266 | if let hir::BindByRef(_) = bm { | |
267 | if let ty::TyRef(_, mt) = ty.sty { | |
268 | ty = mt.ty; | |
269 | } else { | |
270 | bug!("`ref {}` has wrong type {}", ident.node, ty); | |
271 | } | |
272 | } | |
273 | ||
274 | PatternKind::Binding { | |
275 | mutability: mutability, | |
276 | mode: mode, | |
277 | name: ident.node, | |
278 | var: id, | |
279 | ty: var_ty, | |
280 | subpattern: self.lower_opt_pattern(sub), | |
281 | } | |
282 | } | |
283 | ||
476ff2be SL |
284 | PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => { |
285 | let def = self.tcx.tables().qpath_def(qpath, pat.id); | |
c30ab7b3 SL |
286 | let pat_ty = self.tcx.tables().node_id_to_type(pat.id); |
287 | let adt_def = match pat_ty.sty { | |
288 | ty::TyAdt(adt_def, _) => adt_def, | |
289 | _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"), | |
290 | }; | |
476ff2be | 291 | let variant_def = adt_def.variant_of_def(def); |
c30ab7b3 SL |
292 | |
293 | let subpatterns = | |
294 | subpatterns.iter() | |
295 | .enumerate_and_adjust(variant_def.fields.len(), ddpos) | |
296 | .map(|(i, field)| FieldPattern { | |
297 | field: Field::new(i), | |
298 | pattern: self.lower_pattern(field), | |
299 | }) | |
300 | .collect(); | |
476ff2be | 301 | self.lower_variant_or_leaf(def, subpatterns) |
c30ab7b3 SL |
302 | } |
303 | ||
476ff2be SL |
304 | PatKind::Struct(ref qpath, ref fields, _) => { |
305 | let def = self.tcx.tables().qpath_def(qpath, pat.id); | |
c30ab7b3 SL |
306 | let pat_ty = self.tcx.tables().node_id_to_type(pat.id); |
307 | let adt_def = match pat_ty.sty { | |
308 | ty::TyAdt(adt_def, _) => adt_def, | |
309 | _ => { | |
310 | span_bug!( | |
311 | pat.span, | |
312 | "struct pattern not applied to an ADT"); | |
313 | } | |
314 | }; | |
476ff2be | 315 | let variant_def = adt_def.variant_of_def(def); |
c30ab7b3 SL |
316 | |
317 | let subpatterns = | |
318 | fields.iter() | |
319 | .map(|field| { | |
320 | let index = variant_def.index_of_field_named(field.node.name); | |
321 | let index = index.unwrap_or_else(|| { | |
322 | span_bug!( | |
323 | pat.span, | |
324 | "no field with name {:?}", | |
325 | field.node.name); | |
326 | }); | |
327 | FieldPattern { | |
328 | field: Field::new(index), | |
329 | pattern: self.lower_pattern(&field.node.pat), | |
330 | } | |
331 | }) | |
332 | .collect(); | |
333 | ||
476ff2be | 334 | self.lower_variant_or_leaf(def, subpatterns) |
c30ab7b3 SL |
335 | } |
336 | }; | |
337 | ||
338 | Pattern { | |
339 | span: pat.span, | |
340 | ty: ty, | |
341 | kind: Box::new(kind), | |
342 | } | |
343 | } | |
344 | ||
345 | fn lower_patterns(&mut self, pats: &[P<hir::Pat>]) -> Vec<Pattern<'tcx>> { | |
346 | pats.iter().map(|p| self.lower_pattern(p)).collect() | |
347 | } | |
348 | ||
349 | fn lower_opt_pattern(&mut self, pat: &Option<P<hir::Pat>>) -> Option<Pattern<'tcx>> | |
350 | { | |
351 | pat.as_ref().map(|p| self.lower_pattern(p)) | |
352 | } | |
353 | ||
354 | fn flatten_nested_slice_patterns( | |
355 | &mut self, | |
356 | prefix: Vec<Pattern<'tcx>>, | |
357 | slice: Option<Pattern<'tcx>>, | |
358 | suffix: Vec<Pattern<'tcx>>) | |
359 | -> (Vec<Pattern<'tcx>>, Option<Pattern<'tcx>>, Vec<Pattern<'tcx>>) | |
360 | { | |
361 | let orig_slice = match slice { | |
362 | Some(orig_slice) => orig_slice, | |
363 | None => return (prefix, slice, suffix) | |
364 | }; | |
365 | let orig_prefix = prefix; | |
366 | let orig_suffix = suffix; | |
367 | ||
368 | // dance because of intentional borrow-checker stupidity. | |
369 | let kind = *orig_slice.kind; | |
370 | match kind { | |
371 | PatternKind::Slice { prefix, slice, mut suffix } | | |
372 | PatternKind::Array { prefix, slice, mut suffix } => { | |
373 | let mut orig_prefix = orig_prefix; | |
374 | ||
375 | orig_prefix.extend(prefix); | |
376 | suffix.extend(orig_suffix); | |
377 | ||
378 | (orig_prefix, slice, suffix) | |
379 | } | |
380 | _ => { | |
381 | (orig_prefix, Some(Pattern { | |
382 | kind: box kind, ..orig_slice | |
383 | }), orig_suffix) | |
384 | } | |
385 | } | |
386 | } | |
387 | ||
388 | fn slice_or_array_pattern( | |
389 | &mut self, | |
390 | span: Span, | |
391 | ty: Ty<'tcx>, | |
392 | prefix: &[P<hir::Pat>], | |
393 | slice: &Option<P<hir::Pat>>, | |
394 | suffix: &[P<hir::Pat>]) | |
395 | -> PatternKind<'tcx> | |
396 | { | |
397 | let prefix = self.lower_patterns(prefix); | |
398 | let slice = self.lower_opt_pattern(slice); | |
399 | let suffix = self.lower_patterns(suffix); | |
400 | let (prefix, slice, suffix) = | |
401 | self.flatten_nested_slice_patterns(prefix, slice, suffix); | |
402 | ||
403 | match ty.sty { | |
404 | ty::TySlice(..) => { | |
405 | // matching a slice or fixed-length array | |
406 | PatternKind::Slice { prefix: prefix, slice: slice, suffix: suffix } | |
407 | } | |
408 | ||
409 | ty::TyArray(_, len) => { | |
410 | // fixed-length array | |
411 | assert!(len >= prefix.len() + suffix.len()); | |
412 | PatternKind::Array { prefix: prefix, slice: slice, suffix: suffix } | |
413 | } | |
414 | ||
415 | _ => { | |
416 | span_bug!(span, "bad slice pattern type {:?}", ty); | |
417 | } | |
418 | } | |
419 | } | |
420 | ||
421 | fn lower_variant_or_leaf( | |
422 | &mut self, | |
476ff2be | 423 | def: Def, |
c30ab7b3 SL |
424 | subpatterns: Vec<FieldPattern<'tcx>>) |
425 | -> PatternKind<'tcx> | |
426 | { | |
476ff2be | 427 | match def { |
c30ab7b3 SL |
428 | Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { |
429 | let enum_id = self.tcx.parent_def_id(variant_id).unwrap(); | |
430 | let adt_def = self.tcx.lookup_adt_def(enum_id); | |
431 | if adt_def.variants.len() > 1 { | |
432 | PatternKind::Variant { | |
433 | adt_def: adt_def, | |
434 | variant_index: adt_def.variant_index_with_id(variant_id), | |
435 | subpatterns: subpatterns, | |
436 | } | |
437 | } else { | |
438 | PatternKind::Leaf { subpatterns: subpatterns } | |
439 | } | |
440 | } | |
441 | ||
442 | Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | | |
443 | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => { | |
444 | PatternKind::Leaf { subpatterns: subpatterns } | |
445 | } | |
446 | ||
476ff2be | 447 | _ => bug!() |
c30ab7b3 SL |
448 | } |
449 | } | |
450 | } | |
451 | ||
452 | pub trait PatternFoldable<'tcx> : Sized { | |
453 | fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
454 | self.super_fold_with(folder) | |
455 | } | |
456 | ||
457 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self; | |
458 | } | |
459 | ||
460 | pub trait PatternFolder<'tcx> : Sized { | |
461 | fn fold_pattern(&mut self, pattern: &Pattern<'tcx>) -> Pattern<'tcx> { | |
462 | pattern.super_fold_with(self) | |
463 | } | |
464 | ||
465 | fn fold_pattern_kind(&mut self, kind: &PatternKind<'tcx>) -> PatternKind<'tcx> { | |
466 | kind.super_fold_with(self) | |
467 | } | |
468 | } | |
469 | ||
470 | ||
471 | impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Box<T> { | |
472 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
473 | let content: T = (**self).fold_with(folder); | |
474 | box content | |
475 | } | |
476 | } | |
477 | ||
478 | impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Vec<T> { | |
479 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
480 | self.iter().map(|t| t.fold_with(folder)).collect() | |
481 | } | |
482 | } | |
483 | ||
484 | impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> { | |
485 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self{ | |
486 | self.as_ref().map(|t| t.fold_with(folder)) | |
487 | } | |
488 | } | |
489 | ||
476ff2be SL |
490 | macro_rules! CloneImpls { |
491 | (<$lt_tcx:tt> $($ty:ty),+) => { | |
c30ab7b3 | 492 | $( |
476ff2be SL |
493 | impl<$lt_tcx> PatternFoldable<$lt_tcx> for $ty { |
494 | fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self { | |
495 | Clone::clone(self) | |
c30ab7b3 SL |
496 | } |
497 | } | |
498 | )+ | |
499 | } | |
500 | } | |
501 | ||
476ff2be SL |
502 | CloneImpls!{ <'tcx> |
503 | Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal, | |
504 | Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef | |
505 | } | |
c30ab7b3 SL |
506 | |
507 | impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> { | |
508 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
509 | FieldPattern { | |
510 | field: self.field.fold_with(folder), | |
511 | pattern: self.pattern.fold_with(folder) | |
512 | } | |
513 | } | |
514 | } | |
515 | ||
516 | impl<'tcx> PatternFoldable<'tcx> for Pattern<'tcx> { | |
517 | fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
518 | folder.fold_pattern(self) | |
519 | } | |
520 | ||
521 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
522 | Pattern { | |
523 | ty: self.ty.fold_with(folder), | |
524 | span: self.span.fold_with(folder), | |
525 | kind: self.kind.fold_with(folder) | |
526 | } | |
527 | } | |
528 | } | |
529 | ||
530 | impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> { | |
531 | fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
532 | folder.fold_pattern_kind(self) | |
533 | } | |
534 | ||
535 | fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self { | |
536 | match *self { | |
537 | PatternKind::Wild => PatternKind::Wild, | |
538 | PatternKind::Binding { | |
539 | mutability, | |
540 | name, | |
541 | mode, | |
542 | var, | |
543 | ty, | |
544 | ref subpattern, | |
545 | } => PatternKind::Binding { | |
546 | mutability: mutability.fold_with(folder), | |
547 | name: name.fold_with(folder), | |
548 | mode: mode.fold_with(folder), | |
549 | var: var.fold_with(folder), | |
550 | ty: ty.fold_with(folder), | |
551 | subpattern: subpattern.fold_with(folder), | |
552 | }, | |
553 | PatternKind::Variant { | |
554 | adt_def, | |
555 | variant_index, | |
556 | ref subpatterns, | |
557 | } => PatternKind::Variant { | |
558 | adt_def: adt_def.fold_with(folder), | |
559 | variant_index: variant_index.fold_with(folder), | |
560 | subpatterns: subpatterns.fold_with(folder) | |
561 | }, | |
562 | PatternKind::Leaf { | |
563 | ref subpatterns, | |
564 | } => PatternKind::Leaf { | |
565 | subpatterns: subpatterns.fold_with(folder), | |
566 | }, | |
567 | PatternKind::Deref { | |
568 | ref subpattern, | |
569 | } => PatternKind::Deref { | |
570 | subpattern: subpattern.fold_with(folder), | |
571 | }, | |
572 | PatternKind::Constant { | |
573 | ref value | |
574 | } => PatternKind::Constant { | |
575 | value: value.fold_with(folder) | |
576 | }, | |
577 | PatternKind::Range { | |
578 | ref lo, | |
579 | ref hi | |
580 | } => PatternKind::Range { | |
581 | lo: lo.fold_with(folder), | |
582 | hi: hi.fold_with(folder) | |
583 | }, | |
584 | PatternKind::Slice { | |
585 | ref prefix, | |
586 | ref slice, | |
587 | ref suffix, | |
588 | } => PatternKind::Slice { | |
589 | prefix: prefix.fold_with(folder), | |
590 | slice: slice.fold_with(folder), | |
591 | suffix: suffix.fold_with(folder) | |
592 | }, | |
593 | PatternKind::Array { | |
594 | ref prefix, | |
595 | ref slice, | |
596 | ref suffix | |
597 | } => PatternKind::Array { | |
598 | prefix: prefix.fold_with(folder), | |
599 | slice: slice.fold_with(folder), | |
600 | suffix: suffix.fold_with(folder) | |
601 | }, | |
602 | } | |
603 | } | |
604 | } |