]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #55819 - pnkfelix:issue-55810-must-typeck-pats-eagerly, r=oli-obk
authorPietro Albini <pietro@pietroalbini.org>
Sat, 10 Nov 2018 23:21:21 +0000 (00:21 +0100)
committerGitHub <noreply@github.com>
Sat, 10 Nov 2018 23:21:21 +0000 (00:21 +0100)
Typecheck patterns of all match arms first, so we get types for bindings

Fix eventually (after backport to beta) the issue #55810

src/librustc_typeck/check/_match.rs
src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs [new file with mode: 0644]

index 4a300fe09215cbfc01e2dbd068b409dbfb2e400e..a477df6ae2d568e4d296876c7a9fd0c91a442612 100644 (file)
@@ -626,9 +626,9 @@ pub fn check_match(&self,
         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 @@ pub fn check_match(&self,
                 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 (file)
index 0000000..9eed80a
--- /dev/null
@@ -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 => {}
+    }
+}