about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-09-06 09:36:39 +0200
committerGitHub <noreply@github.com>2019-09-06 09:36:39 +0200
commit3c1630aa386582644759514f74b2b0a7601fb379 (patch)
treed37aefb8ec1e33b0f1292f1743cb623ca37e17e9 /src/libsyntax_ext
parentab75a1713a00e6d61a2bdf4ddc3d36713f03ce19 (diff)
parent16ba5029a19eaa5968e61f4447a2d3ebf3367dc2 (diff)
Rollup merge of #64111 - Centril:ast-only-patkind-or, r=petrochenkov
or-patterns: Uniformly use `PatKind::Or` in AST & Fix/Cleanup resolve

Following up on work in https://github.com/rust-lang/rust/pull/63693 and https://github.com/rust-lang/rust/pull/61708, in this PR we:

- Uniformly use `PatKind::Or(...)` in AST:

   - Change `ast::Arm.pats: Vec<P<Pat>>` => `ast::Arm.pat: P<Pat>`

   - Change `ast::ExprKind::Let.0: Vec<P<Pat>>` => `ast::ExprKind::Let.0: P<Pat>`

- Adjust `librustc_resolve/late.rs` to correctly handle or-patterns at any level of nesting as a result.

  In particular, the already-bound check which rejects e.g. `let (a, a);` now accounts for or-patterns. The consistency checking (ensures no missing bindings and binding mode consistency) also now accounts for or-patterns. In the process, a bug was found in the current compiler which allowed:

   ```rust
   enum E<T> { A(T, T), B(T) }
   use E::*;
   fn foo() {
       match A(0, 1) {
           B(mut a) | A(mut a, mut a) => {}
       }
   }
   ```

   The new algorithms took a few iterations to get right. I tried several clever schemes but ultimately a version based on a stack of hashsets and recording product/sum contexts was chosen since it is more clearly correct.

- Clean up `librustc_resolve/late.rs` by, among other things, using a new `with_rib` function to better ensure stack dicipline.

- Do not push the change in AST to HIR for now to avoid doing too much in this PR. To cope with  this, we introduce a temporary hack in `rustc::hir::lowering` (clearly marked in the diff).

cc https://github.com/rust-lang/rust/issues/54883
cc @dlrobertson @matthewjasper
r? @petrochenkov
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/deriving/cmp/ord.rs6
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_ord.rs4
-rw-r--r--src/libsyntax_ext/deriving/decodable.rs4
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs6
-rw-r--r--src/libsyntax_ext/format.rs2
5 files changed, 9 insertions, 13 deletions
diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs
index 55687c3175b..1f4f5aa3709 100644
--- a/src/libsyntax_ext/deriving/cmp/ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/ord.rs
@@ -95,11 +95,9 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<
                     cx.expr_call_global(span, cmp_path.clone(), args)
                 };
 
-                let eq_arm = cx.arm(span,
-                                    vec![cx.pat_path(span, equals_path.clone())],
-                                    old);
+                let eq_arm = cx.arm(span, cx.pat_path(span, equals_path.clone()), old);
                 let neq_arm = cx.arm(span,
-                                     vec![cx.pat_ident(span, test_id)],
+                                     cx.pat_ident(span, test_id),
                                      cx.expr_ident(span, test_id));
 
                 cx.expr_match(span, new, vec![eq_arm, neq_arm])
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 740b92a9b79..debdc300e64 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -160,10 +160,10 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
                 };
 
                 let eq_arm = cx.arm(span,
-                                    vec![cx.pat_some(span, cx.pat_path(span, ordering.clone()))],
+                                    cx.pat_some(span, cx.pat_path(span, ordering.clone())),
                                     old);
                 let neq_arm = cx.arm(span,
-                                    vec![cx.pat_ident(span, test_id)],
+                                    cx.pat_ident(span, test_id),
                                     cx.expr_ident(span, test_id));
 
                 cx.expr_match(span, new, vec![eq_arm, neq_arm])
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index 9b6f8518de0..d3d604b7252 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -119,9 +119,7 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
                                                     vec![idx, exprdecode.clone()]))
                 });
 
-                arms.push(cx.arm(v_span,
-                                 vec![cx.pat_lit(v_span, cx.expr_usize(v_span, i))],
-                                 decoded));
+                arms.push(cx.arm(v_span, cx.pat_lit(v_span, cx.expr_usize(v_span, i)), decoded));
             }
 
             arms.push(cx.arm_unreachable(trait_span));
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 6fd763f5a91..893d89f06a1 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1071,7 +1071,7 @@ impl<'a> MethodDef<'a> {
         for (arg_expr, pat) in self_args.iter().zip(patterns) {
             body = cx.expr_match(trait_.span,
                                  arg_expr.clone(),
-                                 vec![cx.arm(trait_.span, vec![pat.clone()], body)])
+                                 vec![cx.arm(trait_.span, pat.clone(), body)])
         }
 
         body
@@ -1311,7 +1311,7 @@ impl<'a> MethodDef<'a> {
                                                              nonself_args,
                                                              &substructure);
 
-                cx.arm(sp, vec![single_pat], arm_expr)
+                cx.arm(sp, single_pat, arm_expr)
             })
             .collect();
 
@@ -1337,7 +1337,7 @@ impl<'a> MethodDef<'a> {
             _ => None,
         };
         if let Some(arm) = default {
-            match_arms.push(cx.arm(sp, vec![cx.pat_wild(sp)], arm));
+            match_arms.push(cx.arm(sp, cx.pat_wild(sp), arm));
         }
 
         // We will usually need the catch-all after matching the
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index ad275f421af..e29f12c50c5 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -716,7 +716,7 @@ impl<'a, 'b> Context<'a, 'b> {
         // But the nested match expression is proved to perform not as well
         // as series of let's; the first approach does.
         let pat = self.ecx.pat_tuple(self.fmtsp, pats);
-        let arm = self.ecx.arm(self.fmtsp, vec![pat], args_array);
+        let arm = self.ecx.arm(self.fmtsp, pat, args_array);
         let head = self.ecx.expr(self.fmtsp, ast::ExprKind::Tup(heads));
         let result = self.ecx.expr_match(self.fmtsp, head, vec![arm]);