Repository: rust-analyzer/rust-analyzer
Pull request #5368 (2020-07-14 11:13:43)

Compress match checking tests


bors r+
🤖


Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index a5a4b3ccd6..3adf9e6ca0 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -95,40 +95,6 @@ jobs:
       if: matrix.os == 'windows-latest'
       run: Remove-Item ./target/debug/xtask.exe, ./target/debug/deps/xtask.exe
 
-  # Weird target to catch non-portable code
-  rust-power:
-    name: Rust Power
-    runs-on: ubuntu-latest
-
-    steps:
-    - name: Checkout repository
-      uses: actions/checkout@v2
-
-    - name: Install Rust toolchain
-      uses: actions-rs/toolchain@v1
-      with:
-        toolchain: stable
-        profile: minimal
-        override: true
-        target: 'powerpc-unknown-linux-gnu'
-
-    - run: sudo chown -R $(whoami):$(id -ng) ~/.cargo/
-
-    - name: Cache cargo registry
-      uses: actions/cache@v1
-      with:
-        path: ~/.cargo/registry
-        key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
-
-    - name: Cache cargo index
-      uses: actions/cache@v1
-      with:
-        path: ~/.cargo/git
-        key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
-
-    - name: Check
-      run: cargo check --target=powerpc-unknown-linux-gnu --all-targets
-
   typescript:
     name: TypeScript
     strategy:
@@ -137,7 +103,7 @@ jobs:
         os: [ubuntu-latest, windows-latest, macos-latest]
 
     runs-on: ${{ matrix.os }}
-
+    
     steps:
     - name: Checkout repository
       uses: actions/checkout@v2
diff --git a/crates/expect/Cargo.toml b/crates/expect/Cargo.toml
index 77775630dc..f8fa29e4e9 100644
--- a/crates/expect/Cargo.toml
+++ b/crates/expect/Cargo.toml
@@ -3,7 +3,6 @@ name = "expect"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 edition = "2018"
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml
index bea4856948..dc26b8ce76 100644
--- a/crates/flycheck/Cargo.toml
+++ b/crates/flycheck/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "flycheck"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/paths/Cargo.toml b/crates/paths/Cargo.toml
index cbe2c26e20..646ee7fd54 100644
--- a/crates/paths/Cargo.toml
+++ b/crates/paths/Cargo.toml
@@ -3,7 +3,6 @@ name = "paths"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 edition = "2018"
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_arena/Cargo.toml b/crates/ra_arena/Cargo.toml
index 66c3738f4d..d287dbb735 100644
--- a/crates/ra_arena/Cargo.toml
+++ b/crates/ra_arena/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_arena"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_assists/Cargo.toml b/crates/ra_assists/Cargo.toml
index bd2905f080..3bcf58ba4b 100644
--- a/crates/ra_assists/Cargo.toml
+++ b/crates/ra_assists/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_assists"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_cfg/Cargo.toml b/crates/ra_cfg/Cargo.toml
index 6425cd6d6f..9165076a58 100644
--- a/crates/ra_cfg/Cargo.toml
+++ b/crates/ra_cfg/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_cfg"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index 5f334d04f1..889142442a 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_db"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_fmt/Cargo.toml b/crates/ra_fmt/Cargo.toml
index b4ef93f2b2..e9d057afc0 100644
--- a/crates/ra_fmt/Cargo.toml
+++ b/crates/ra_fmt/Cargo.toml
@@ -4,7 +4,6 @@ name = "ra_fmt"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index c260bb193c..512676c996 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_hir"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index 1ec619b428..cf5ebbaf5a 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_hir_def"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_hir_expand/Cargo.toml b/crates/ra_hir_expand/Cargo.toml
index 6da0e2a165..e5c9f3e997 100644
--- a/crates/ra_hir_expand/Cargo.toml
+++ b/crates/ra_hir_expand/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_hir_expand"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 78f5e55bb8..90368220b9 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_hir_ty"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 3623b8569e..3016ca3bd5 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -244,3 +244,28 @@ impl AstDiagnostic for MismatchedArgCount {
         ast::CallExpr::cast(node).unwrap()
     }
 }
+
+#[cfg(test)]
+fn check_diagnostics(ra_fixture: &str) {
+    use ra_db::{fixture::WithFixture, FileId};
+    use ra_syntax::TextRange;
+    use rustc_hash::FxHashMap;
+
+    use crate::test_db::TestDB;
+
+    let db = TestDB::with_files(ra_fixture);
+    let annotations = db.extract_annotations();
+
+    let mut actual: FxHashMap<FileId, Vec<(TextRange, String)>> = FxHashMap::default();
+    db.diag(|d| {
+        // FXIME: macros...
+        let file_id = d.source().file_id.original_file(&db);
+        let range = d.syntax_node(&db).text_range();
+        // FIXME: support multi-line messages in annotations
+        let message = d.message().lines().next().unwrap().to_owned();
+        actual.entry(file_id).or_default().push((range, message));
+    });
+    actual.values_mut().for_each(|diags| diags.sort_by_key(|it| it.0.start()));
+
+    assert_eq!(annotations, actual);
+}
diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs
index 239be779fa..277ace1802 100644
--- a/crates/ra_hir_ty/src/diagnostics/expr.rs
+++ b/crates/ra_hir_ty/src/diagnostics/expr.rs
@@ -376,146 +376,117 @@ pub fn record_pattern_missing_fields(
 
 #[cfg(test)]
 mod tests {
-    use expect::{expect, Expect};
-    use ra_db::fixture::WithFixture;
-
-    use crate::{diagnostics::MismatchedArgCount, test_db::TestDB};
-
-    fn check_diagnostic(ra_fixture: &str, expect: Expect) {
-        let msg = TestDB::with_single_file(ra_fixture).0.diagnostic::<MismatchedArgCount>().0;
-        expect.assert_eq(&msg);
-    }
-
-    fn check_no_diagnostic(ra_fixture: &str) {
-        let (s, diagnostic_count) =
-            TestDB::with_single_file(ra_fixture).0.diagnostic::<MismatchedArgCount>();
-
-        assert_eq!(0, diagnostic_count, "expected no diagnostic, found one: {}", s);
-    }
+    use crate::diagnostics::check_diagnostics;
 
     #[test]
     fn simple_free_fn_zero() {
-        check_diagnostic(
-            r"
-            fn zero() {}
-            fn f() { zero(1); }
-            ",
-            expect![["\"zero(1)\": Expected 0 arguments, found 1\n"]],
+        check_diagnostics(
+            r#"
+fn zero() {}
+fn f() { zero(1); }
+       //^^^^^^^ Expected 0 arguments, found 1
+"#,
         );
 
-        check_no_diagnostic(
-            r"
-            fn zero() {}
-            fn f() { zero(); }
-            ",
+        check_diagnostics(
+            r#"
+fn zero() {}
+fn f() { zero(); }
+"#,
         );
     }
 
     #[test]
     fn simple_free_fn_one() {
-        check_diagnostic(
-            r"
-            fn one(arg: u8) {}
-            fn f() { one(); }
-            ",
-            expect![["\"one()\": Expected 1 argument, found 0\n"]],
+        check_diagnostics(
+            r#"
+fn one(arg: u8) {}
+fn f() { one(); }
+       //^^^^^ Expected 1 argument, found 0
+"#,
         );
 
-        check_no_diagnostic(
-            r"
-            fn one(arg: u8) {}
-            fn f() { one(1); }
-            ",
+        check_diagnostics(
+            r#"
+fn one(arg: u8) {}
+fn f() { one(1); }
+"#,
         );
     }
 
     #[test]
     fn method_as_fn() {
-        check_diagnostic(
-            r"
-            struct S;
-            impl S {
-                fn method(&self) {}
-            }
-
-            fn f() {
-                S::method();
-            }
-            ",
-            expect![["\"S::method()\": Expected 1 argument, found 0\n"]],
+        check_diagnostics(
+            r#"
+struct S;
+impl S { fn method(&self) {} }
+
+fn f() {
+    S::method();
+} //^^^^^^^^^^^ Expected 1 argument, found 0
+"#,
         );
 
-        check_no_diagnostic(
-            r"
-            struct S;
-            impl S {
-                fn method(&self) {}
-            }
+        check_diagnostics(
+            r#"
+struct S;
+impl S { fn method(&self) {} }
 
-            fn f() {
-                S::method(&S);
-                S.method();
-            }
-            ",
+fn f() {
+    S::method(&S);
+    S.method();
+}
+"#,
         );
     }
 
     #[test]
     fn method_with_arg() {
-        check_diagnostic(
-            r"
-            struct S;
-            impl S {
-                fn method(&self, arg: u8) {}
-            }
+        check_diagnostics(
+            r#"
+struct S;
+impl S { fn method(&self, arg: u8) {} }
 
             fn f() {
                 S.method();
-            }
-            ",
-            expect![["\"S.method()\": Expected 1 argument, found 0\n"]],
+            } //^^^^^^^^^^ Expected 1 argument, found 0
+            "#,
         );
 
-        check_no_diagnostic(
-            r"
-            struct S;
-            impl S {
-                fn method(&self, arg: u8) {}
-            }
+        check_diagnostics(
+            r#"
+struct S;
+impl S { fn method(&self, arg: u8) {} }
 
-            fn f() {
-                S::method(&S, 0);
-                S.method(1);
-            }
-            ",
+fn f() {
+    S::method(&S, 0);
+    S.method(1);
+}
+"#,
         );
     }
 
     #[test]
     fn tuple_struct() {
-        check_diagnostic(
-            r"
-            struct Tup(u8, u16);
-            fn f() {
-                Tup(0);
-            }
-            ",
-            expect![["\"Tup(0)\": Expected 2 arguments, found 1\n"]],
+        check_diagnostics(
+            r#"
+struct Tup(u8, u16);
+fn f() {
+    Tup(0);
+} //^^^^^^ Expected 2 arguments, found 1
+"#,
         )
     }
 
     #[test]
     fn enum_variant() {
-        check_diagnostic(
-            r"
-            enum En {
-                Variant(u8, u16),
-            }
-            fn f() {
-                En::Variant(0);
-            }
-            ",
-            expect![["\"En::Variant(0)\": Expected 2 arguments, found 1\n"]],
+        check_diagnostics(
+            r#"
+enum En { Variant(u8, u16), }
+fn f() {
+    En::Variant(0);
+} //^^^^^^^^^^^^^^ Expected 2 arguments, found 1
+"#,
         )
     }
 }
diff --git a/crates/ra_hir_ty/src/diagnostics/match_check.rs b/crates/ra_hir_ty/src/diagnostics/match_check.rs
index 899025a879..ba48b51b5e 100644
--- a/crates/ra_hir_ty/src/diagnostics/match_check.rs
+++ b/crates/ra_hir_ty/src/diagnostics/match_check.rs
@@ -41,9 +41,9 @@
 //! ```ignore
 //! // x: (Option<bool>, Result<()>)
 //! match x {
-//!     (Some(true), _) => {}
-//!     (None, Err(())) => {}
-//!     (None, Err(_)) => {}
+//!     (Some(true), _) => (),
+//!     (None, Err(())) => (),
+//!     (None, Err(_)) => (),
 //! }
 //! ```
 //!
@@ -837,685 +837,251 @@ fn enum_variant_matches(cx: &MatchCheckCtx, pat_id: PatId, enum_variant_id: Enum
 
 #[cfg(test)]
 mod tests {
-    use insta::assert_snapshot;
-    use ra_db::fixture::WithFixture;
-
-    use crate::{diagnostics::MissingMatchArms, test_db::TestDB};
-
-    fn check_diagnostic_message(ra_fixture: &str) -> String {
-        TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>().0
-    }
-
-    fn check_diagnostic(ra_fixture: &str) {
-        let diagnostic_count =
-            TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>().1;
-
-        assert_eq!(1, diagnostic_count, "no diagnostic reported");
-    }
-
-    fn check_no_diagnostic(ra_fixture: &str) {
-        let (s, diagnostic_count) =
-            TestDB::with_single_file(ra_fixture).0.diagnostic::<MissingMatchArms>();
-
-        assert_eq!(0, diagnostic_count, "expected no diagnostic, found one: {}", s);
-    }
-
-    #[test]
-    fn empty_tuple_no_arms_diagnostic_message() {
-        assert_snapshot!(
-            check_diagnostic_message(r"
-                fn test_fn() {
-                    match () {
-                    }
-                }
-            "),
-            @"\"()\": Missing match arm\n"
-        );
-    }
-
-    #[test]
-    fn empty_tuple_no_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match () {
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn empty_tuple_wild() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match () {
-                    _ => {}
-                }
-            }
-        ",
-        );
-    }
+    use crate::diagnostics::check_diagnostics;
 
     #[test]
-    fn empty_tuple_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match () {
-                    () => {}
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_empty_tuple_no_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (()) {
-                }
-            }
-        ",
-        );
-    }
+    fn empty_tuple() {
+        check_diagnostics(
+            r#"
+fn main() {
+    match () { }
+        //^^ Missing match arm
+   match (()) { }
+       //^^^^ Missing match arm
 
-    #[test]
-    fn tuple_of_empty_tuple_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (()) {
-                    (()) => {}
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_two_empty_tuple_no_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match ((), ()) {
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_two_empty_tuple_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match ((), ()) {
-                    ((), ()) => {}
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn bool_no_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match false {
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn bool_missing_arm() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match false {
-                    true => {}
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn bool_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match false {
-                    true => {}
-                    false => {}
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_bools_no_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_bools_missing_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                    (true, true) => {},
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_bools_missing_arm() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                    (false, true) => {},
-                    (false, false) => {},
-                    (true, false) => {},
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_bools_with_wilds() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                    (false, _) => {},
-                    (true, false) => {},
-                    (_, true) => {},
-                }
-            }
-        ",
+    match () { _ => (), }
+    match () { () => (), }
+    match (()) { (()) => (), }
+}
+"#,
         );
     }
 
     #[test]
-    fn tuple_of_bools_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                    (true, true) => {},
-                    (true, false) => {},
-                    (false, true) => {},
-                    (false, false) => {},
-                }
-            }
-        ",
-        );
-    }
+    fn tuple_of_two_empty_tuple() {
+        check_diagnostics(
+            r#"
+fn main() {
+    match ((), ()) { }
+        //^^^^^^^^ Missing match arm
 
-    #[test]
-    fn tuple_of_bools_binding_missing_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                    (true, _x) => {},
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn tuple_of_bools_binding_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true) {
-                    (true, _x) => {},
-                    (false, true) => {},
-                    (false, false) => {},
-                }
-            }
-        ",
+    match ((), ()) { ((), ()) => (), }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn boolean() {
+        check_diagnostics(
+            r#"
+fn test_main() {
+    match false { }
+        //^^^^^ Missing match arm
+    match false { true => (), }
+        //^^^^^ Missing match arm
+    match (false, true) {}
+        //^^^^^^^^^^^^^ Missing match arm
+    match (false, true) { (true, true) => (), }
+        //^^^^^^^^^^^^^ Missing match arm
+    match (false, true) {
+        //^^^^^^^^^^^^^ Missing match arm
+        (false, true) => (),
+        (false, false) => (),
+        (true, false) => (),
+    }
+    match (false, true) { (true, _x) => (), }
+        //^^^^^^^^^^^^^ Missing match arm
+
+    match false { true => (), false => (), }
+    match (false, true) {
+        (false, _) => (),
+        (true, false) => (),
+        (_, true) => (),
+    }
+    match (false, true) {
+        (true, true) => (),
+        (true, false) => (),
+        (false, true) => (),
+        (false, false) => (),
+    }
+    match (false, true) {
+        (true, _x) => (),
+        (false, true) => (),
+        (false, false) => (),
+    }
+    match (false, true, false) {
+        (false, ..) => (),
+        (true, ..) => (),
+    }
+    match (false, true, false) {
+        (.., false) => (),
+        (.., true) => (),
+    }
+    match (false, true, false) { (..) => (), }
+}
+"#,
         );
     }
 
     #[test]
-    fn tuple_of_bools_with_ellipsis_at_end_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true, false) {
-                    (false, ..) => {},
-                    (true, ..) => {},
-                }
-            }
-        ",
-        );
-    }
+    fn tuple_of_tuple_and_bools() {
+        check_diagnostics(
+            r#"
+fn main() {
+    match (false, ((), false)) {}
+        //^^^^^^^^^^^^^^^^^^^^ Missing match arm
+    match (false, ((), false)) { (true, ((), true)) => (), }
+        //^^^^^^^^^^^^^^^^^^^^ Missing match arm
+    match (false, ((), false)) { (true, _) => (), }
+        //^^^^^^^^^^^^^^^^^^^^ Missing match arm
 
-    #[test]
-    fn tuple_of_bools_with_ellipsis_at_beginning_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true, false) {
-                    (.., false) => {},
-                    (.., true) => {},
-                }
-            }
-        ",
-        );
+    match (false, ((), false)) {
+        (true, ((), true)) => (),
+        (true, ((), false)) => (),
+        (false, ((), true)) => (),
+        (false, ((), false)) => (),
     }
-
-    #[test]
-    fn tuple_of_bools_with_ellipsis_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, true, false) {
-                    (..) => {},
-                }
-            }
-        ",
-        );
+    match (false, ((), false)) {
+        (true, ((), true)) => (),
+        (true, ((), false)) => (),
+        (false, _) => (),
     }
-
-    #[test]
-    fn tuple_of_tuple_and_bools_no_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, ((), false)) {
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn tuple_of_tuple_and_bools_missing_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, ((), false)) {
-                    (true, ((), true)) => {},
-                }
-            }
-        ",
-        );
-    }
+    fn enums() {
+        check_diagnostics(
+            r#"
+enum Either { A, B, }
 
-    #[test]
-    fn tuple_of_tuple_and_bools_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, ((), false)) {
-                    (true, ((), true)) => {},
-                    (true, ((), false)) => {},
-                    (false, ((), true)) => {},
-                    (false, ((), false)) => {},
-                }
-            }
-        ",
-        );
-    }
+fn main() {
+    match Either::A { }
+        //^^^^^^^^^ Missing match arm
+    match Either::B { Either::A => (), }
+        //^^^^^^^^^ Missing match arm
 
-    #[test]
-    fn tuple_of_tuple_and_bools_wildcard_missing_arms() {
-        check_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, ((), false)) {
-                    (true, _) => {},
-                }
-            }
-        ",
-        );
+    match &Either::B {
+        //^^^^^^^^^^ Missing match arm
+        Either::A => (),
     }
 
-    #[test]
-    fn tuple_of_tuple_and_bools_wildcard_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (false, ((), false)) {
-                    (true, ((), true)) => {},
-                    (true, ((), false)) => {},
-                    (false, _) => {},
-                }
-            }
-        ",
-        );
+    match Either::B {
+        Either::A => (), Either::B => (),
     }
-
-    #[test]
-    fn enum_no_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match Either::A {
-                }
-            }
-        ",
-        );
+    match &Either::B {
+        Either::A => (), Either::B => (),
     }
-
-    #[test]
-    fn enum_missing_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A => {},
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn enum_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A => {},
-                    Either::B => {},
-                }
-            }
-        ",
-        );
-    }
+    fn enum_containing_bool() {
+        check_diagnostics(
+            r#"
+enum Either { A(bool), B }
 
-    #[test]
-    fn enum_ref_missing_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match &Either::B {
-                    Either::A => {},
-                }
-            }
-        ",
-        );
+fn main() {
+    match Either::B { }
+        //^^^^^^^^^ Missing match arm
+    match Either::B {
+        //^^^^^^^^^ Missing match arm
+        Either::A(true) => (), Either::B => ()
     }
 
-    #[test]
-    fn enum_ref_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match &Either::B {
-                    Either::A => {},
-                    Either::B => {},
-                }
-            }
-        ",
-        );
+    match Either::B {
+        Either::A(true) => (),
+        Either::A(false) => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn enum_containing_bool_no_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                }
-            }
-        ",
-        );
+    match Either::B {
+        Either::B => (),
+        _ => (),
     }
-
-    #[test]
-    fn enum_containing_bool_missing_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(true) => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
+    match Either::B {
+        Either::A(_) => (),
+        Either::B => (),
     }
 
-    #[test]
-    fn enum_containing_bool_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(true) => (),
-                    Either::A(false) => (),
-                    Either::B => (),
-                }
-            }
-        ",
+}
+        "#,
         );
     }
 
     #[test]
-    fn enum_containing_bool_with_wild_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::B => (),
-                    _ => (),
-                }
-            }
-        ",
-        );
-    }
+    fn enum_different_sizes() {
+        check_diagnostics(
+            r#"
+enum Either { A(bool), B(bool, bool) }
 
-    #[test]
-    fn enum_containing_bool_with_wild_2_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(_) => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
+fn main() {
+    match Either::A(false) {
+        //^^^^^^^^^^^^^^^^ Missing match arm
+        Either::A(_) => (),
+        Either::B(false, _) => (),
     }
 
-    #[test]
-    fn enum_different_sizes_missing_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B(bool, bool),
-            }
-            fn test_fn() {
-                match Either::A(false) {
-                    Either::A(_) => (),
-                    Either::B(false, _) => (),
-                }
-            }
-        ",
-        );
+    match Either::A(false) {
+        Either::A(_) => (),
+        Either::B(true, _) => (),
+        Either::B(false, _) => (),
     }
-
-    #[test]
-    fn enum_different_sizes_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B(bool, bool),
-            }
-            fn test_fn() {
-                match Either::A(false) {
-                    Either::A(_) => (),
-                    Either::B(true, _) => (),
-                    Either::B(false, _) => (),
-                }
-            }
-        ",
-        );
+    match Either::A(false) {
+        Either::A(true) | Either::A(false) => (),
+        Either::B(true, _) => (),
+        Either::B(false, _) => (),
     }
-
-    #[test]
-    fn or_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B(bool, bool),
-            }
-            fn test_fn() {
-                match Either::A(false) {
-                    Either::A(true) | Either::A(false) => (),
-                    Either::B(true, _) => (),
-                    Either::B(false, _) => (),
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
     fn tuple_of_enum_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool),
-                B(bool, bool),
-            }
-            enum Either2 {
-                C,
-                D,
-            }
-            fn test_fn() {
-                match (Either::A(false), Either2::C) {
-                    (Either::A(true), _) | (Either::A(false), _) => (),
-                    (Either::B(true, _), Either2::C) => (),
-                    (Either::B(false, _), Either2::C) => (),
-                    (Either::B(_, _), Either2::D) => (),
-                }
-            }
-        ",
-        );
+        check_diagnostics(
+            r#"
+enum Either { A(bool), B(bool, bool) }
+enum Either2 { C, D }
+
+fn main() {
+    match (Either::A(false), Either2::C) {
+        (Either::A(true), _) | (Either::A(false), _) => (),
+        (Either::B(true, _), Either2::C) => (),
+        (Either::B(false, _), Either2::C) => (),
+        (Either::B(_, _), Either2::D) => (),
     }
-
-    #[test]
-    fn mismatched_types() {
-        // Match statements with arms that don't match the
-        // expression pattern do not fire this diagnostic.
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            enum Either2 {
-                C,
-                D,
-            }
-            fn test_fn() {
-                match Either::A {
-                    Either2::C => (),
-                    Either2::D => (),
-                }
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn mismatched_types_with_different_arity() {
-        // Match statements with arms that don't match the
-        // expression pattern do not fire this diagnostic.
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (true, false) {
-                    (true, false, true) => (),
-                    (true) => (),
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn malformed_match_arm_tuple_missing_pattern() {
+    fn mismatched_types() {
         // Match statements with arms that don't match the
         // expression pattern do not fire this diagnostic.
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match (0) {
-                    () => (),
-                }
-            }
-        ",
+        check_diagnostics(
+            r#"
+enum Either { A, B }
+enum Either2 { C, D }
+
+fn main() {
+    match Either::A {
+        Either2::C => (),
+        Either2::D => (),
+    }
+    match (true, false) {
+        (true, false, true) => (),
+        (true) => (),
+    }
+    match (0) { () => () }
+    match Unresolved::Bar { Unresolved::Baz => () }
+}
+        "#,
         );
     }
 
@@ -1523,517 +1089,247 @@ mod tests {
     fn malformed_match_arm_tuple_enum_missing_pattern() {
         // We are testing to be sure we don't panic here when the match
         // arm `Either::B` is missing its pattern.
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B(u32),
-            }
-            fn test_fn() {
-                match Either::A {
-                    Either::A => (),
-                    Either::B() => (),
-                }
-            }
-        ",
-        );
-    }
+        check_diagnostics(
+            r#"
+enum Either { A, B(u32) }
 
-    #[test]
-    fn enum_not_in_scope() {
-        // The enum is not in scope so we don't perform exhaustiveness
-        // checking, but we want to be sure we don't panic here (and
-        // we don't create a diagnostic).
-        check_no_diagnostic(
-            r"
-            fn test_fn() {
-                match Foo::Bar {
-                    Foo::Baz => (),
-                }
-            }
-        ",
+fn main() {
+    match Either::A {
+        Either::A => (),
+        Either::B() => (),
+    }
+}
+"#,
         );
     }
 
     #[test]
     fn expr_diverges() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match loop {} {
-                    Either::A => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
-    }
+        check_diagnostics(
+            r#"
+enum Either { A, B }
 
-    #[test]
-    fn expr_loop_with_break() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match loop { break Foo::A } {
-                    Either::A => (),
-                    Either::B => (),
-                }
-            }
-        ",
+fn main() {
+    match loop {} {
+        Either::A => (),
+        Either::B => (),
+    }
+    match loop {} {
+        Either::A => (),
+    }
+    match loop { break Foo::A } {
+        //^^^^^^^^^^^^^^^^^^^^^ Missing match arm
+        Either::A => (),
+    }
+    match loop { break Foo::A } {
+        Either::A => (),
+        Either::B => (),
+    }
+}
+"#,
         );
     }
 
     #[test]
     fn expr_partially_diverges() {
-        check_no_diagnostic(
-            r"
-            enum Either<T> {
-                A(T),
-                B,
-            }
-            fn foo() -> Either<!> {
-                Either::B
-            }
-            fn test_fn() -> u32 {
-                match foo() {
-                    Either::A(val) => val,
-                    Either::B => 0,
-                }
-            }
-        ",
-        );
-    }
+        check_diagnostics(
+            r#"
+enum Either<T> { A(T), B }
 
-    #[test]
-    fn enum_record_no_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                }
-            }
-        ",
-        );
+fn foo() -> Either<!> { Either::B }
+fn main() -> u32 {
+    match foo() {
+        Either::A(val) => val,
+        Either::B => 0,
     }
-
-    #[test]
-    fn enum_record_missing_arms() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                    Either::A { foo: true } => (),
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn enum_record_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                    Either::A { foo: true } => (),
-                    Either::A { foo: false } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
-    }
+    fn enum_record() {
+        check_diagnostics(
+            r#"
+enum Either { A { foo: bool }, B }
 
-    #[test]
-    fn enum_record_missing_field_no_diagnostic() {
-        // When `Either::A` is missing a struct member, we don't want
-        // to fire the missing match arm diagnostic. This should fire
-        // some other diagnostic.
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::B;
-                match a {
-                    Either::A { } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
+fn main() {
+    let a = Either::A { foo: true };
+    match a { }
+        //^ Missing match arm
+    match a { Either::A { foo: true } => () }
+        //^ Missing match arm
+    match a {
+        Either::A { } => (),
+                //^^^ Missing structure fields:
+        Either::B => (),
     }
+    match a {
+        //^ Missing match arm
+        Either::A { } => (),
+    }           //^^^ Missing structure fields:
 
-    #[test]
-    fn enum_record_missing_field_missing_match_arm() {
-        // Even though `Either::A` is missing fields, we still want to fire
-        // the missing arm diagnostic here, since we know `Either::B` is missing.
-        check_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::B;
-                match a {
-                    Either::A { } => (),
-                }
-            }
-        ",
-        );
+    match a {
+        Either::A { foo: true } => (),
+        Either::A { foo: false } => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn enum_record_no_diagnostic_wild() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                    Either::A { foo: _ } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
+    match a {
+        Either::A { foo: _ } => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn enum_record_fields_out_of_order_missing_arm() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool, bar: () },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                    Either::A { bar: (), foo: false } => (),
-                    Either::A { foo: true, bar: () } => (),
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn enum_record_fields_out_of_order_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool, bar: () },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                    Either::A { bar: (), foo: false } => (),
-                    Either::A { foo: true, bar: () } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
-    }
+    fn enum_record_fields_out_of_order() {
+        check_diagnostics(
+            r#"
+enum Either {
+    A { foo: bool, bar: () },
+    B,
+}
 
-    #[test]
-    fn enum_record_ellipsis_missing_arm() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool, bar: bool },
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A { foo: true, .. } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
+fn main() {
+    let a = Either::A { foo: true, bar: () };
+    match a {
+        //^ Missing match arm
+        Either::A { bar: (), foo: false } => (),
+        Either::A { foo: true, bar: () } => (),
     }
 
-    #[test]
-    fn enum_record_ellipsis_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool, bar: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::A { foo: true };
-                match a {
-                    Either::A { foo: true, .. } => (),
-                    Either::A { foo: false, .. } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
+    match a {
+        Either::A { bar: (), foo: false } => (),
+        Either::A { foo: true, bar: () } => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn enum_record_ellipsis_all_fields_missing_arm() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool, bar: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::B;
-                match a {
-                    Either::A { .. } => (),
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn enum_record_ellipsis_all_fields_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A { foo: bool, bar: bool },
-                B,
-            }
-            fn test_fn() {
-                let a = Either::B;
-                match a {
-                    Either::A { .. } => (),
-                    Either::B => (),
-                }
-            }
-        ",
-        );
-    }
+    fn enum_record_ellipsis() {
+        check_diagnostics(
+            r#"
+enum Either {
+    A { foo: bool, bar: bool },
+    B,
+}
 
-    #[test]
-    fn enum_tuple_partial_ellipsis_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool, bool, bool, bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(true, .., true) => {},
-                    Either::A(true, .., false) => {},
-                    Either::A(false, .., true) => {},
-                    Either::A(false, .., false) => {},
-                    Either::B => {},
-                }
-            }
-        ",
-        );
+fn main() {
+    let a = Either::B;
+    match a {
+        //^ Missing match arm
+        Either::A { foo: true, .. } => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn enum_tuple_partial_ellipsis_2_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool, bool, bool, bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(true, .., true) => {},
-                    Either::A(true, .., false) => {},
-                    Either::A(.., true) => {},
-                    Either::A(.., false) => {},
-                    Either::B => {},
-                }
-            }
-        ",
-        );
+    match a {
+        //^ Missing match arm
+        Either::A { .. } => (),
     }
 
-    #[test]
-    fn enum_tuple_partial_ellipsis_missing_arm() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A(bool, bool, bool, bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(true, .., true) => {},
-                    Either::A(true, .., false) => {},
-                    Either::A(false, .., false) => {},
-                    Either::B => {},
-                }
-            }
-        ",
-        );
+    match a {
+        Either::A { foo: true, .. } => (),
+        Either::A { foo: false, .. } => (),
+        Either::B => (),
     }
 
-    #[test]
-    fn enum_tuple_partial_ellipsis_2_missing_arm() {
-        check_diagnostic(
-            r"
-            enum Either {
-                A(bool, bool, bool, bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(true, .., true) => {},
-                    Either::A(true, .., false) => {},
-                    Either::A(.., true) => {},
-                    Either::B => {},
-                }
-            }
-        ",
-        );
+    match a {
+        Either::A { .. } => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn enum_tuple_ellipsis_no_diagnostic() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A(bool, bool, bool, bool),
-                B,
-            }
-            fn test_fn() {
-                match Either::B {
-                    Either::A(..) => {},
-                    Either::B => {},
-                }
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn enum_never() {
-        check_no_diagnostic(
-            r"
-            enum Never {}
+    fn enum_tuple_partial_ellipsis() {
+        check_diagnostics(
+            r#"
+enum Either {
+    A(bool, bool, bool, bool),
+    B,
+}
 
-            fn test_fn(never: Never) {
-                match never {}
-            }
-        ",
-        );
+fn main() {
+    match Either::B {
+        //^^^^^^^^^ Missing match arm
+        Either::A(true, .., true) => (),
+        Either::A(true, .., false) => (),
+        Either::A(false, .., false) => (),
+        Either::B => (),
+    }
+    match Either::B {
+        //^^^^^^^^^ Missing match arm
+        Either::A(true, .., true) => (),
+        Either::A(true, .., false) => (),
+        Either::A(.., true) => (),
+        Either::B => (),
+    }
+
+    match Either::B {
+        Either::A(true, .., true) => (),
+        Either::A(true, .., false) => (),
+        Either::A(false, .., true) => (),
+        Either::A(false, .., false) => (),
+        Either::B => (),
+    }
+    match Either::B {
+        Either::A(true, .., true) => (),
+        Either::A(true, .., false) => (),
+        Either::A(.., true) => (),
+        Either::A(.., false) => (),
+        Either::B => (),
     }
-
-    #[test]
-    fn type_never() {
-        check_no_diagnostic(
-            r"
-            fn test_fn(never: !) {
-                match never {}
-            }
-        ",
+}
+"#,
         );
     }
 
     #[test]
-    fn enum_never_ref() {
-        check_no_diagnostic(
-            r"
-            enum Never {}
+    fn never() {
+        check_diagnostics(
+            r#"
+enum Never {}
 
-            fn test_fn(never: &Never) {
-                match never {}
-            }
-        ",
-        );
-    }
-
-    #[test]
-    fn expr_diverges_missing_arm() {
-        check_no_diagnostic(
-            r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match loop {} {
-                    Either::A => (),
-                }
-            }
-        ",
+fn enum_(never: Never) {
+    match never {}
+}
+fn enum_ref(never: &Never) {
+    match never {}
+}
+fn bang(never: !) {
+    match never {}
+}
+"#,
         );
     }
 
     #[test]
     fn or_pattern_panic() {
-        check_no_diagnostic(
-            r"
-            pub enum Category {
-                Infinity,
-                Zero,
-            }
+        check_diagnostics(
+            r#"
+pub enum Category { Infinity, Zero }
 
-            fn panic(a: Category, b: Category) {
-                match (a, b) {
-                    (Category::Zero | Category::Infinity, _) => {}
-                    (_, Category::Zero | Category::Infinity) => {}
-                }
-            }
-        ",
-        );
+fn panic(a: Category, b: Category) {
+    match (a, b) {
+        (Category::Zero | Category::Infinity, _) => (),
+        (_, Category::Zero | Category::Infinity) => (),
     }
 
-    #[test]
-    fn or_pattern_panic_2() {
-        // FIXME: This is a false positive, but the code used to cause a panic in the match checker,
-        // so this acts as a regression test for that.
-        check_diagnostic(
-            r"
-            pub enum Category {
-                Infinity,
-                Zero,
-            }
-
-            fn panic(a: Category, b: Category) {
-                match (a, b) {
-                    (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => {}
-
-                    (Category::Infinity | Category::Zero, _) => {}
-                }
-            }
-        ",
+    // FIXME: This is a false positive, but the code used to cause a panic in the match checker,
+    // so this acts as a regression test for that.
+    match (a, b) {
+        //^^^^^^ Missing match arm
+        (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => (),
+        (Category::Infinity | Category::Zero, _) => (),
+    }
+}
+"#,
         );
     }
 
@@ -2051,105 +1347,72 @@ mod tests {
 
         #[test]
         fn integers() {
-            // This is a false negative.
             // We don't currently check integer exhaustiveness.
-            check_no_diagnostic(
-                r"
-            fn test_fn() {
-                match 5 {
-                    10 => (),
-                    11..20 => (),
-                }
-            }
-        ",
+            check_diagnostics(
+                r#"
+fn main() {
+    match 5 {
+        10 => (),
+        11..20 => (),
+    }
+}
+"#,
             );
         }
 
         #[test]
         fn internal_or() {
-            // This is a false negative.
             // We do not currently handle patterns with internal `or`s.
-            check_no_diagnostic(
-                r"
-            fn test_fn() {
-                enum Either {
-                    A(bool),
-                    B,
-                }
-                match Either::B {
-                    Either::A(true | false) => (),
-                }
-            }
-        ",
-            );
-        }
-
-        #[test]
-        fn expr_loop_missing_arm() {
-            // This is a false negative.
-            // We currently infer the type of `loop { break Foo::A }` to `!`, which
-            // causes us to skip the diagnostic since `Either::A` doesn't type check
-            // with `!`.
-            check_diagnostic(
-                r"
-            enum Either {
-                A,
-                B,
-            }
-            fn test_fn() {
-                match loop { break Foo::A } {
-                    Either::A => (),
-                }
-            }
-        ",
+            check_diagnostics(
+                r#"
+fn main() {
+    enum Either { A(bool), B }
+    match Either::B {
+        Either::A(true | false) => (),
+    }
+}
+"#,
             );
         }
 
         #[test]
         fn tuple_of_bools_with_ellipsis_at_end_missing_arm() {
-            // This is a false negative.
             // We don't currently handle tuple patterns with ellipsis.
-            check_no_diagnostic(
-                r"
-            fn test_fn() {
-                match (false, true, false) {
-                    (false, ..) => {},
-                }
-            }
-        ",
+            check_diagnostics(
+                r#"
+fn main() {
+    match (false, true, false) {
+        (false, ..) => (),
+    }
+}
+"#,
             );
         }
 
         #[test]
         fn tuple_of_bools_with_ellipsis_at_beginning_missing_arm() {
-            // This is a false negative.
             // We don't currently handle tuple patterns with ellipsis.
-            check_no_diagnostic(
-                r"
-            fn test_fn() {
-                match (false, true, false) {
-                    (.., false) => {},
-                }
-            }
-        ",
+            check_diagnostics(
+                r#"
+fn main() {
+    match (false, true, false) {
+        (.., false) => (),
+    }
+}
+"#,
             );
         }
 
         #[test]
         fn struct_missing_arm() {
-            // This is a false negative.
             // We don't currently handle structs.
-            check_no_diagnostic(
-                r"
-            struct Foo {
-                a: bool,
-            }
-            fn test_fn(f: Foo) {
-                match f {
-                    Foo { a: true } => {},
-                }
-            }
-        ",
+            check_diagnostics(
+                r#"
+struct Foo { a: bool }
+fn main(f: Foo) {
+    match f { Foo { a: true } => () }
+}
+"#,
             );
         }
     }
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml
index 6f81074912..df2fad5201 100644
--- a/crates/ra_ide/Cargo.toml
+++ b/crates/ra_ide/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_ide"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_ide_db/Cargo.toml b/crates/ra_ide_db/Cargo.toml
index bcddad60cf..c3921bd406 100644
--- a/crates/ra_ide_db/Cargo.toml
+++ b/crates/ra_ide_db/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_ide_db"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_mbe/Cargo.toml b/crates/ra_mbe/Cargo.toml
index a26746a194..4dec24914b 100644
--- a/crates/ra_mbe/Cargo.toml
+++ b/crates/ra_mbe/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_mbe"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_parser/Cargo.toml b/crates/ra_parser/Cargo.toml
index 72ec3e4d9a..0da581fd53 100644
--- a/crates/ra_parser/Cargo.toml
+++ b/crates/ra_parser/Cargo.toml
@@ -4,7 +4,6 @@ name = "ra_parser"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_proc_macro/Cargo.toml b/crates/ra_proc_macro/Cargo.toml
index c4b6e9e7ba..d009ceb82e 100644
--- a/crates/ra_proc_macro/Cargo.toml
+++ b/crates/ra_proc_macro/Cargo.toml
@@ -4,7 +4,6 @@ name = "ra_proc_macro"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_proc_macro_srv/Cargo.toml b/crates/ra_proc_macro_srv/Cargo.toml
index 12ce497f87..5821029450 100644
--- a/crates/ra_proc_macro_srv/Cargo.toml
+++ b/crates/ra_proc_macro_srv/Cargo.toml
@@ -4,7 +4,6 @@ name = "ra_proc_macro_srv"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml
index 69ac51c9e2..eabfcebb07 100644
--- a/crates/ra_prof/Cargo.toml
+++ b/crates/ra_prof/Cargo.toml
@@ -4,7 +4,6 @@ name = "ra_prof"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index 827eb7e28e..b1b44dcf78 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_project_model"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_text_edit/Cargo.toml b/crates/ra_text_edit/Cargo.toml
index dbb2233504..46a2ab68f4 100644
--- a/crates/ra_text_edit/Cargo.toml
+++ b/crates/ra_text_edit/Cargo.toml
@@ -4,7 +4,6 @@ name = "ra_text_edit"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_toolchain/Cargo.toml b/crates/ra_toolchain/Cargo.toml
index 84b748c0a4..038c29ded6 100644
--- a/crates/ra_toolchain/Cargo.toml
+++ b/crates/ra_toolchain/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_toolchain"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/ra_tt/Cargo.toml b/crates/ra_tt/Cargo.toml
index 3c45248c3e..b5b12e3afe 100644
--- a/crates/ra_tt/Cargo.toml
+++ b/crates/ra_tt/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "ra_tt"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 370b130901..c02f72517b 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -4,7 +4,6 @@ name = "rust-analyzer"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 autobins = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml
index 4c0b858617..f9e380c105 100644
--- a/crates/stdx/Cargo.toml
+++ b/crates/stdx/Cargo.toml
@@ -3,7 +3,6 @@ name = "stdx"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 edition = "2018"
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/vfs-notify/Cargo.toml b/crates/vfs-notify/Cargo.toml
index 95c56ffa6d..eb1764c369 100644
--- a/crates/vfs-notify/Cargo.toml
+++ b/crates/vfs-notify/Cargo.toml
@@ -3,7 +3,6 @@ name = "vfs-notify"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 edition = "2018"
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml
index b74cdb7ffa..db99707b3f 100644
--- a/crates/vfs/Cargo.toml
+++ b/crates/vfs/Cargo.toml
@@ -3,7 +3,6 @@ name = "vfs"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 edition = "2018"
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index d1cfb59090..8045a98eaf 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -4,7 +4,6 @@ name = "xtask"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
 publish = false
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false


Test patch:
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index ddafd0ea13..fb8723fb78 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -82,7 +82,7 @@ impl FileLoader for TestDB {
 }
 
 impl TestDB {
-    pub fn module_for_file(&self, file_id: FileId) -> ModuleId {
+    pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
         for &krate in self.relevant_crates(file_id).iter() {
             let crate_def_map = self.crate_def_map(krate);
             for (local_id, data) in crate_def_map.modules.iter() {
@@ -94,7 +94,7 @@ impl TestDB {
         panic!("Can't find module for file")
     }
 
-    fn diag<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) {
+    pub(crate) fn diag<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) {
         let crate_graph = self.crate_graph();
         for krate in crate_graph.iter() {
             let crate_def_map = self.crate_def_map(krate);
@@ -124,7 +124,7 @@ impl TestDB {
         }
     }
 
-    pub fn diagnostics(&self) -> (String, u32) {
+    pub(crate) fn diagnostics(&self) -> (String, u32) {
         let mut buf = String::new();
         let mut count = 0;
         self.diag(|d| {
@@ -134,22 +134,7 @@ impl TestDB {
         (buf, count)
     }
 
-    /// Like `diagnostics`, but filtered for a single diagnostic.
-    pub fn diagnostic<D: Diagnostic>(&self) -> (String, u32) {
-        let mut buf = String::new();
-        let mut count = 0;
-        self.diag(|d| {
-            // We want to filter diagnostics by the particular one we are testing for, to
-            // avoid surprising results in tests.
-            if d.downcast_ref::<D>().is_some() {
-                format_to!(buf, "{:?}: {}\n", d.syntax_node(self).text(), d.message());
-                count += 1;
-            };
-        });
-        (buf, count)
-    }
-
-    pub fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
+    pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
         let mut files = Vec::new();
         let crate_graph = self.crate_graph();
         for krate in crate_graph.iter() {
diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml
index e719f4f7c1..6821db1e81 100644
--- a/crates/test_utils/Cargo.toml
+++ b/crates/test_utils/Cargo.toml
@@ -3,7 +3,6 @@ edition = "2018"
 name = "test_utils"
 version = "0.1.0"
 authors = ["rust-analyzer developers"]
-license = "MIT OR Apache-2.0"
 
 [lib]
 doctest = false