about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorFabian Wolff <fabian.wolff@alumni.ethz.ch>2021-09-12 02:05:07 +0200
committerFabian Wolff <fabian.wolff@alumni.ethz.ch>2021-09-12 02:05:07 +0200
commit2bff77d255b9960489459157900a95a6e5a8279f (patch)
treeacb1df952727728eb624c3493e99cd77dcdabd3b /compiler
parent497ee321af3b8496eaccd7af7b437f18bab81abf (diff)
downloadrust-2bff77d255b9960489459157900a95a6e5a8279f.tar.gz
rust-2bff77d255b9960489459157900a95a6e5a8279f.zip
Fix suggestion for nested struct patterns
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_passes/src/liveness.rs23
1 files changed, 15 insertions, 8 deletions
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index ab9bfea9694..55de2e9d2f8 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -265,12 +265,13 @@ impl IrMaps<'tcx> {
         self.capture_info_map.insert(hir_id, Rc::new(cs));
     }
 
-    fn add_from_pat(&mut self, pat: &hir::Pat<'tcx>) {
+    fn collect_shorthand_field_ids(&self, pat: &hir::Pat<'tcx>) -> HirIdSet {
         // For struct patterns, take note of which fields used shorthand
         // (`x` rather than `x: x`).
         let mut shorthand_field_ids = HirIdSet::default();
         let mut pats = VecDeque::new();
         pats.push_back(pat);
+
         while let Some(pat) = pats.pop_front() {
             use rustc_hir::PatKind::*;
             match &pat.kind {
@@ -278,8 +279,10 @@ impl IrMaps<'tcx> {
                     pats.extend(inner_pat.iter());
                 }
                 Struct(_, fields, _) => {
-                    let ids = fields.iter().filter(|f| f.is_shorthand).map(|f| f.pat.hir_id);
-                    shorthand_field_ids.extend(ids);
+                    let (short, not_short): (Vec<&_>, Vec<&_>) =
+                        fields.iter().partition(|f| f.is_shorthand);
+                    shorthand_field_ids.extend(short.iter().map(|f| f.pat.hir_id));
+                    pats.extend(not_short.iter().map(|f| f.pat));
                 }
                 Ref(inner_pat, _) | Box(inner_pat) => {
                     pats.push_back(inner_pat);
@@ -296,6 +299,12 @@ impl IrMaps<'tcx> {
             }
         }
 
+        return shorthand_field_ids;
+    }
+
+    fn add_from_pat(&mut self, pat: &hir::Pat<'tcx>) {
+        let shorthand_field_ids = self.collect_shorthand_field_ids(pat);
+
         pat.each_binding(|_, hir_id, _, ident| {
             self.add_live_node_for_node(hir_id, VarDefNode(ident.span, hir_id));
             self.add_variable(Local(LocalInfo {
@@ -373,15 +382,13 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
     }
 
     fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
+        let shorthand_field_ids = self.collect_shorthand_field_ids(param.pat);
         param.pat.each_binding(|_bm, hir_id, _x, ident| {
             let var = match param.pat.kind {
-                rustc_hir::PatKind::Struct(_, fields, _) => Local(LocalInfo {
+                rustc_hir::PatKind::Struct(..) => Local(LocalInfo {
                     id: hir_id,
                     name: ident.name,
-                    is_shorthand: fields
-                        .iter()
-                        .find(|f| f.ident == ident)
-                        .map_or(false, |f| f.is_shorthand),
+                    is_shorthand: shorthand_field_ids.contains(&hir_id),
                 }),
                 _ => Param(hir_id, ident.name),
             };