about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-14 11:13:58 +0000
committerGitHub <noreply@github.com>2020-07-14 11:13:58 +0000
commit735baad6cea6d8f317fc83f2f077cd7148dcb3d9 (patch)
treefc82048ad3ff5103f19fc27206e0fcf1353e17a6
parent510866b4a1a812414568bd96f1d197587ead78c0 (diff)
parentb031899dac6ad5847cc2f5551766a567657f095d (diff)
downloadrust-735baad6cea6d8f317fc83f2f077cd7148dcb3d9.tar.gz
rust-735baad6cea6d8f317fc83f2f077cd7148dcb3d9.zip
Merge #5368
5368: Compress match checking tests r=matklad a=matklad



bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs25
-rw-r--r--crates/ra_hir_ty/src/diagnostics/expr.rs169
-rw-r--r--crates/ra_hir_ty/src/diagnostics/match_check.rs1561
-rw-r--r--crates/ra_hir_ty/src/test_db.rs23
4 files changed, 511 insertions, 1267 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 3623b8569e3..3016ca3bd58 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 239be779fa1..277ace1802a 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 899025a8797..ba48b51b5ea 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_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index ddafd0ea130..fb8723fb78f 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() {