about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-11-11 00:21:21 +0100
committerGitHub <noreply@github.com>2018-11-11 00:21:21 +0100
commitc4ca49aebd3a25c080cdc8efa64586637b90c90b (patch)
treee569477a420f0ea2e8e0fe1f94b57f73df77eb72
parente8a3934599bbb2dbd285c6259cac71f70c1ec3e6 (diff)
parent5f91373c778da7d28306d0faba590a22612c281b (diff)
downloadrust-c4ca49aebd3a25c080cdc8efa64586637b90c90b.tar.gz
rust-c4ca49aebd3a25c080cdc8efa64586637b90c90b.zip
Rollup merge of #55819 - pnkfelix:issue-55810-must-typeck-pats-eagerly, r=oli-obk
Typecheck patterns of all match arms first, so we get types for bindings

Fix eventually (after backport to beta) the issue #55810
-rw-r--r--src/librustc_typeck/check/_match.rs8
-rw-r--r--src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs23
2 files changed, 27 insertions, 4 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 4a300fe0921..a477df6ae2d 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -626,9 +626,9 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
         let discrim_diverges = self.diverges.get();
         self.diverges.set(Diverges::Maybe);
 
-        // Typecheck the patterns first, so that we get types for all the
-        // bindings.
-        let all_arm_pats_diverge = arms.iter().map(|arm| {
+        // rust-lang/rust#55810: Typecheck patterns first (via eager
+        // collection into `Vec`), so we get types for all bindings.
+        let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
             let mut all_pats_diverge = Diverges::WarnedAlways;
             for p in &arm.pats {
                 self.diverges.set(Diverges::Maybe);
@@ -644,7 +644,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 Diverges::Maybe => Diverges::Maybe,
                 Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
             }
-        });
+        }).collect();
 
         // Now typecheck the blocks.
         //
diff --git a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
new file mode 100644
index 00000000000..9eed80ad886
--- /dev/null
+++ b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
@@ -0,0 +1,23 @@
+// compile-pass
+
+// rust-lang/rust#55810: types for a binding in a match arm can be
+// inferred from arms that come later in the match.
+
+struct S;
+
+impl S {
+    fn method(&self) -> bool {
+        unimplemented!()
+    }
+}
+
+fn get<T>() -> T {
+    unimplemented!()
+}
+
+fn main() {
+    match get() {
+        x if x.method() => {}
+        &S => {}
+    }
+}