From 3a93a0e860486f3748ef934332477d54a2f1ebbc Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 18:19:14 +0100 Subject: [PATCH 01/12] HAIR lowering: improve code quality for slices --- src/librustc_mir/hair/pattern/mod.rs | 45 +++++++++++----------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 0086c3b0e103f..48e5ee48a024b 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -557,14 +557,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ty::Slice(..) | ty::Array(..) => self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix), - ty::Error => { // Avoid ICE - return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; - } - _ => - span_bug!( - pat.span, - "unexpanded type for vector pattern: {:?}", - ty), + // Avoid ICE + ty::Error => return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }, + _ => span_bug!( + pat.span, + "unexpanded type for vector pattern: {:?}", + ty + ), } } @@ -698,9 +697,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { &mut self, prefix: Vec>, slice: Option>, - suffix: Vec>) - -> (Vec>, Option>, Vec>) - { + suffix: Vec>, + ) -> (Vec>, Option>, Vec>) { let orig_slice = match slice { Some(orig_slice) => orig_slice, None => return (prefix, slice, suffix) @@ -734,31 +732,24 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ty: Ty<'tcx>, prefix: &'tcx [P], slice: &'tcx Option>, - suffix: &'tcx [P]) - -> PatKind<'tcx> - { + suffix: &'tcx [P], + ) -> PatKind<'tcx> { let prefix = self.lower_patterns(prefix); let slice = self.lower_opt_pattern(slice); let suffix = self.lower_patterns(suffix); - let (prefix, slice, suffix) = - self.flatten_nested_slice_patterns(prefix, slice, suffix); + let (prefix, slice, suffix) = self.flatten_nested_slice_patterns(prefix, slice, suffix); + // Some validation: match ty.kind { - ty::Slice(..) => { - // matching a slice or fixed-length array - PatKind::Slice { prefix: prefix, slice: slice, suffix: suffix } - } - + // Matching a slice, `[T]`. + ty::Slice(..) => PatKind::Slice { prefix, slice, suffix }, + // Fixed-length array, `[T; len]`. ty::Array(_, len) => { - // fixed-length array let len = len.eval_usize(self.tcx, self.param_env); assert!(len >= prefix.len() as u64 + suffix.len() as u64); - PatKind::Array { prefix: prefix, slice: slice, suffix: suffix } - } - - _ => { - span_bug!(span, "bad slice pattern type {:?}", ty); + PatKind::Array { prefix, slice, suffix } } + _ => span_bug!(span, "bad slice pattern type {:?}", ty), } } From 7d99e4e4c2ab30a23bd24565003dfaac4fb1b5d8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 19:18:41 +0100 Subject: [PATCH 02/12] check_pat_slice: shadow 'expected' to make sure it's not used again --- src/librustc_typeck/check/pat.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 4fb57a6562574..0465726c42e34 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1175,8 +1175,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { discrim_span: Option, ) -> Ty<'tcx> { let tcx = self.tcx; - let expected_ty = self.structurally_resolved_type(span, expected); - let (inner_ty, slice_ty) = match expected_ty.kind { + let expected = self.structurally_resolved_type(span, expected); + let (inner_ty, slice_ty) = match expected.kind { // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`. ty::Array(inner_ty, size) => { let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) { @@ -1208,11 +1208,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; (inner_ty, slice_ty) } - ty::Slice(inner_ty) => (inner_ty, expected_ty), + ty::Slice(inner_ty) => (inner_ty, expected), // The expected type must be an array or slice, but was neither, so error. _ => { - if !expected_ty.references_error() { - self.error_expected_array_or_slice(span, expected_ty); + if !expected.references_error() { + self.error_expected_array_or_slice(span, expected); } (tcx.types.err, tcx.types.err) } @@ -1230,7 +1230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for elt in after { self.check_pat(&elt, inner_ty, def_bm, discrim_span); } - expected_ty + expected } fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { From 13b71018c1845d9ab6b80199d20adfc3835f7341 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 19:23:43 +0100 Subject: [PATCH 03/12] `lower_pattern_unadjusted`: remove dead code. The code is dead because `check_pat_slice` will never have `expected = ty::Ref(...)` due to default-binding-modes (see `is_non_ref_pat`, `peel_off_references`). Moreover, if the type is not `ty::Array(_) | ty::Slice(_)` then `check_pat_slice` enters an error branch. --- src/librustc_mir/hair/pattern/mod.rs | 9 --------- src/librustc_typeck/check/pat.rs | 8 ++++---- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 48e5ee48a024b..22426defcd05b 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -545,15 +545,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Slice(ref prefix, ref slice, ref suffix) => { match ty.kind { - ty::Ref(_, ty, _) => - PatKind::Deref { - subpattern: Pat { - ty, - span: pat.span, - kind: Box::new(self.slice_or_array_pattern( - pat.span, ty, prefix, slice, suffix)) - }, - }, ty::Slice(..) | ty::Array(..) => self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix), diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 0465726c42e34..65029048b5ddd 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1176,7 +1176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let tcx = self.tcx; let expected = self.structurally_resolved_type(span, expected); - let (inner_ty, slice_ty) = match expected.kind { + let (inner_ty, slice_ty, expected) = match expected.kind { // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`. ty::Array(inner_ty, size) => { let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) { @@ -1206,15 +1206,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.error_scrutinee_unfixed_length(span); tcx.types.err }; - (inner_ty, slice_ty) + (inner_ty, slice_ty, expected) } - ty::Slice(inner_ty) => (inner_ty, expected), + ty::Slice(inner_ty) => (inner_ty, expected, expected), // The expected type must be an array or slice, but was neither, so error. _ => { if !expected.references_error() { self.error_expected_array_or_slice(span, expected); } - (tcx.types.err, tcx.types.err) + (tcx.types.err, tcx.types.err, tcx.types.err) } }; From ceaec1da06009716f1953d50f73d6cb49c06fb32 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 22:16:33 +0100 Subject: [PATCH 04/12] `check_pat_slice`: extract `check_aray_pat_len`. Also use `types.err` when matching on `expected.kind`s which don't match `ty::Array(..) | ty::Slice(_)`. --- src/librustc_typeck/check/pat.rs | 73 +++++++++++++++++++------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 65029048b5ddd..26e87007adf01 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1174,38 +1174,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_bm: BindingMode, discrim_span: Option, ) -> Ty<'tcx> { - let tcx = self.tcx; + let err = self.tcx.types.err; let expected = self.structurally_resolved_type(span, expected); let (inner_ty, slice_ty, expected) = match expected.kind { // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`. - ty::Array(inner_ty, size) => { - let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) { - // Now we know the length... - let min_len = before.len() as u64 + after.len() as u64; - if slice.is_none() { - // ...and since there is no variable-length pattern, - // we require an exact match between the number of elements - // in the array pattern and as provided by the matched type. - if min_len != size { - self.error_scrutinee_inconsistent_length(span, min_len, size) - } - tcx.types.err - } else if let Some(rest) = size.checked_sub(min_len) { - // The variable-length pattern was there, - // so it has an array type with the remaining elements left as its size... - tcx.mk_array(inner_ty, rest) - } else { - // ...however, in this case, there were no remaining elements. - // That is, the slice pattern requires more than the array type offers. - self.error_scrutinee_with_rest_inconsistent_length(span, min_len, size); - tcx.types.err - } - } else { - // No idea what the length is, which happens if we have e.g., - // `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`. - self.error_scrutinee_unfixed_length(span); - tcx.types.err - }; + ty::Array(inner_ty, len) => { + let min = before.len() as u64 + after.len() as u64; + let slice_ty = self.check_array_pat_len(span, slice, len, min) + .map_or(err, |len| self.tcx.mk_array(inner_ty, len)); (inner_ty, slice_ty, expected) } ty::Slice(inner_ty) => (inner_ty, expected, expected), @@ -1214,7 +1190,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !expected.references_error() { self.error_expected_array_or_slice(span, expected); } - (tcx.types.err, tcx.types.err, tcx.types.err) + (err, err, err) } }; @@ -1233,6 +1209,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected } + /// Type check the length of an array pattern. + /// + /// Return the length of the variable length pattern, + /// if it exists and there are no errors. + fn check_array_pat_len( + &self, + span: Span, + slice: Option<&'tcx Pat>, + len: &ty::Const<'tcx>, + min_len: u64, + ) -> Option { + if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) { + // Now we know the length... + if slice.is_none() { + // ...and since there is no variable-length pattern, + // we require an exact match between the number of elements + // in the array pattern and as provided by the matched type. + if min_len != len { + self.error_scrutinee_inconsistent_length(span, min_len, len); + } + } else if let r @ Some(_) = len.checked_sub(min_len) { + // The variable-length pattern was there, + // so it has an array type with the remaining elements left as its size... + return r; + } else { + // ...however, in this case, there were no remaining elements. + // That is, the slice pattern requires more than the array type offers. + self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len); + } + } else { + // No idea what the length is, which happens if we have e.g., + // `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`. + self.error_scrutinee_unfixed_length(span); + } + None + } + fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { struct_span_err!( self.tcx.sess, From 2a9f1f8c02f8eb87cebe75c6fb8413ae79123c31 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 22:41:34 +0100 Subject: [PATCH 05/12] `lower_pattern_unadjusted`: extract common `ty::Error` code. --- src/librustc_mir/hair/pattern/mod.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 22426defcd05b..8517e2e6fb336 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -445,6 +445,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pat<'tcx> { let mut ty = self.tables.node_type(pat.hir_id); + if let ty::Error = ty.kind { + // Avoid ICEs (e.g., #50577 and #50585). + return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; + } + let kind = match pat.kind { hir::PatKind::Wild => PatKind::Wild, @@ -548,8 +553,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ty::Slice(..) | ty::Array(..) => self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix), - // Avoid ICE - ty::Error => return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }, _ => span_bug!( pat.span, "unexpanded type for vector pattern: {:?}", @@ -572,19 +575,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::Leaf { subpatterns } } - ty::Error => { // Avoid ICE (#50577) - return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; - } _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty), } } hir::PatKind::Binding(_, id, ident, ref sub) => { let var_ty = self.tables.node_type(pat.hir_id); - if let ty::Error = var_ty.kind { - // Avoid ICE - return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; - }; let bm = *self.tables.pat_binding_modes().get(pat.hir_id) .expect("missing binding mode"); let (mutability, mode) = match bm { @@ -624,9 +620,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let res = self.tables.qpath_res(qpath, pat.hir_id); let adt_def = match ty.kind { ty::Adt(adt_def, _) => adt_def, - ty::Error => { // Avoid ICE (#50585) - return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; - } _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", ty), From 3b0af1d87d53a070c3c046a223b78ad62ec901a8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 22:45:42 +0100 Subject: [PATCH 06/12] `lower_pattern_unadjusted`: cleanup `Slice(..)` branch. --- src/librustc_mir/hair/pattern/mod.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 8517e2e6fb336..817ba67c76340 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -550,15 +550,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Slice(ref prefix, ref slice, ref suffix) => { match ty.kind { - ty::Slice(..) | - ty::Array(..) => - self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix), - _ => span_bug!( - pat.span, - "unexpanded type for vector pattern: {:?}", - ty - ), + ty::Slice(..) | ty::Array(..) => {} + _ => span_bug!(pat.span, "unexpanded type for vector pattern: {:?}", ty), } + self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) } hir::PatKind::Tuple(ref subpatterns, ddpos) => { From be6381e9e0d3d883baf3c2557f54af51ca18abb0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 22:51:32 +0100 Subject: [PATCH 07/12] `lower_pattern_unadjusted`: cleanup `Tuple(..)` branch. --- src/librustc_mir/hair/pattern/mod.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 817ba67c76340..888f4b8e115a8 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -557,21 +557,19 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } hir::PatKind::Tuple(ref subpatterns, ddpos) => { - match ty.kind { - ty::Tuple(ref tys) => { - let subpatterns = - subpatterns.iter() - .enumerate_and_adjust(tys.len(), ddpos) - .map(|(i, subpattern)| FieldPat { - field: Field::new(i), - pattern: self.lower_pattern(subpattern) - }) - .collect(); - - PatKind::Leaf { subpatterns } - } + let tys = match ty.kind { + ty::Tuple(ref tys) => tys, _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty), - } + }; + let subpatterns = subpatterns + .iter() + .enumerate_and_adjust(tys.len(), ddpos) + .map(|(i, subpattern)| FieldPat { + field: Field::new(i), + pattern: self.lower_pattern(subpattern) + }) + .collect(); + PatKind::Leaf { subpatterns } } hir::PatKind::Binding(_, id, ident, ref sub) => { From eb020bc245bc51093fc8bbced9c0610d6e23195a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 22:58:20 +0100 Subject: [PATCH 08/12] `lower_pattern_unadjusted`: simplify `Binding(..)` branch. Avoid calling `.node_type(...)` again. --- src/librustc_mir/hair/pattern/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 888f4b8e115a8..7ebef2d983331 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -573,7 +573,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } hir::PatKind::Binding(_, id, ident, ref sub) => { - let var_ty = self.tables.node_type(pat.hir_id); let bm = *self.tables.pat_binding_modes().get(pat.hir_id) .expect("missing binding mode"); let (mutability, mode) = match bm { @@ -591,13 +590,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // A ref x pattern is the same node used for x, and as such it has // x's type, which is &T, where we want T (the type being matched). + let var_ty = ty; if let ty::BindByReference(_) = bm { if let ty::Ref(_, rty, _) = ty.kind { ty = rty; } else { bug!("`ref {}` has wrong type {}", ident, ty); } - } + }; PatKind::Binding { mutability, From d63c324a15d45b5509aff685cad565f1bdcddb85 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 23:09:33 +0100 Subject: [PATCH 09/12] `lower_pattern_unadjusted`: extract `lower_tuple_subpats`. --- src/librustc_mir/hair/pattern/mod.rs | 43 +++++++++++++--------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 7ebef2d983331..4015faf6a906b 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -556,19 +556,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) } - hir::PatKind::Tuple(ref subpatterns, ddpos) => { + hir::PatKind::Tuple(ref pats, ddpos) => { let tys = match ty.kind { ty::Tuple(ref tys) => tys, _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty), }; - let subpatterns = subpatterns - .iter() - .enumerate_and_adjust(tys.len(), ddpos) - .map(|(i, subpattern)| FieldPat { - field: Field::new(i), - pattern: self.lower_pattern(subpattern) - }) - .collect(); + let subpatterns = self.lower_tuple_subpats(pats, tys.len(), ddpos); PatKind::Leaf { subpatterns } } @@ -609,25 +602,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } } - hir::PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => { + hir::PatKind::TupleStruct(ref qpath, ref pats, ddpos) => { let res = self.tables.qpath_res(qpath, pat.hir_id); let adt_def = match ty.kind { ty::Adt(adt_def, _) => adt_def, - _ => span_bug!(pat.span, - "tuple struct pattern not applied to an ADT {:?}", - ty), + _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", ty), }; let variant_def = adt_def.variant_of_res(res); - - let subpatterns = - subpatterns.iter() - .enumerate_and_adjust(variant_def.fields.len(), ddpos) - .map(|(i, field)| FieldPat { - field: Field::new(i), - pattern: self.lower_pattern(field), - }) - .collect(); - + let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos); self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns) } @@ -661,6 +643,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } } + fn lower_tuple_subpats( + &mut self, + pats: &'tcx [P], + expected_len: usize, + gap_pos: Option, + ) -> Vec> { + pats.iter() + .enumerate_and_adjust(expected_len, gap_pos) + .map(|(i, subpattern)| FieldPat { + field: Field::new(i), + pattern: self.lower_pattern(subpattern) + }) + .collect() + } + fn lower_patterns(&mut self, pats: &'tcx [P]) -> Vec> { pats.iter().map(|p| self.lower_pattern(p)).collect() } From cc3160bbbfc42225deba96d98cf7ef709972d748 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 23:14:52 +0100 Subject: [PATCH 10/12] `lower_pattern_unadjusted`: simplify `Or(..)` branch. --- src/librustc_mir/hair/pattern/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 4015faf6a906b..a3d81f0004240 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -629,11 +629,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns) } - hir::PatKind::Or(ref pats) => { - PatKind::Or { - pats: pats.iter().map(|p| self.lower_pattern(p)).collect(), - } - } + hir::PatKind::Or(ref pats) => PatKind::Or { pats: self.lower_patterns(pats) }, }; Pat { From 6286a1d7eb68875504536c78f6316cad7e7490b2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 19 Dec 2019 23:31:27 +0100 Subject: [PATCH 11/12] `slice_or_array_pattern`: remove dead code. After #62550, it is no longer possible for `slice` to be other than `None | Some(Binding(..) | Wild)`. In particular, `lower_pat_slice` may never generate `Some(Array(..) | Slice(..))` and so there is nothing to flatten into `slice`. --- src/librustc_mir/hair/pattern/mod.rs | 43 +--------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index a3d81f0004240..9a0c315683039 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -549,10 +549,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } hir::PatKind::Slice(ref prefix, ref slice, ref suffix) => { - match ty.kind { - ty::Slice(..) | ty::Array(..) => {} - _ => span_bug!(pat.span, "unexpanded type for vector pattern: {:?}", ty), - } self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) } @@ -658,44 +654,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pats.iter().map(|p| self.lower_pattern(p)).collect() } - fn lower_opt_pattern(&mut self, pat: &'tcx Option>) -> Option> - { + fn lower_opt_pattern(&mut self, pat: &'tcx Option>) -> Option> { pat.as_ref().map(|p| self.lower_pattern(p)) } - fn flatten_nested_slice_patterns( - &mut self, - prefix: Vec>, - slice: Option>, - suffix: Vec>, - ) -> (Vec>, Option>, Vec>) { - let orig_slice = match slice { - Some(orig_slice) => orig_slice, - None => return (prefix, slice, suffix) - }; - let orig_prefix = prefix; - let orig_suffix = suffix; - - // dance because of intentional borrow-checker stupidity. - let kind = *orig_slice.kind; - match kind { - PatKind::Slice { prefix, slice, mut suffix } | - PatKind::Array { prefix, slice, mut suffix } => { - let mut orig_prefix = orig_prefix; - - orig_prefix.extend(prefix); - suffix.extend(orig_suffix); - - (orig_prefix, slice, suffix) - } - _ => { - (orig_prefix, Some(Pat { - kind: box kind, ..orig_slice - }), orig_suffix) - } - } - } - fn slice_or_array_pattern( &mut self, span: Span, @@ -707,9 +669,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let prefix = self.lower_patterns(prefix); let slice = self.lower_opt_pattern(slice); let suffix = self.lower_patterns(suffix); - let (prefix, slice, suffix) = self.flatten_nested_slice_patterns(prefix, slice, suffix); - - // Some validation: match ty.kind { // Matching a slice, `[T]`. ty::Slice(..) => PatKind::Slice { prefix, slice, suffix }, From 7353ff20d66267df821d9d161b914ef8fc513304 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 20 Dec 2019 11:54:27 +0100 Subject: [PATCH 12/12] `SliceKind::VarLen`: make doc-comment render correctly. (The backticks were rendering badly in VSCode.) --- src/librustc_mir/hair/pattern/_match.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index c372032850695..f267be812c3d2 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -620,10 +620,11 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { enum SliceKind { /// Patterns of length `n` (`[x, y]`). FixedLen(u64), - /// Patterns using the `..` notation (`[x, .., y]`). Captures any array constructor of `length - /// >= i + j`. In the case where `array_len` is `Some(_)`, this indicates that we only care - /// about the first `i` and the last `j` values of the array, and everything in between is a - /// wildcard `_`. + /// Patterns using the `..` notation (`[x, .., y]`). + /// Captures any array constructor of `length >= i + j`. + /// In the case where `array_len` is `Some(_)`, + /// this indicates that we only care about the first `i` and the last `j` values of the array, + /// and everything in between is a wildcard `_`. VarLen(u64, u64), }