Repository: rust-analyzer/rust-analyzer
Pull request #5458 (2020-07-20 16:23:54)

Use expect in some ra_hir_ty tests

lnicola: https://github.com/rust-analyzer/rust-analyzer/pull/5458/files?w=1

Patch:
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 5a9de3d3ec..b279bdeef6 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -229,11 +229,12 @@ impl CrateDefMap {
     // even), as this should be a great debugging aid.
     pub fn dump(&self) -> String {
         let mut buf = String::new();
-        go(&mut buf, self, "crate", self.root);
-        return buf;
+        go(&mut buf, self, "\ncrate", self.root);
+        return buf.trim().to_string();
 
         fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) {
-            format_to!(buf, "{}\n", path);
+            *buf += path;
+            *buf += "\n";
 
             let mut entries: Vec<_> = map.modules[module].scope.resolutions().collect();
             entries.sort_by_key(|(name, _)| name.clone());
@@ -242,24 +243,23 @@ impl CrateDefMap {
                 format_to!(buf, "{}:", name);
 
                 if def.types.is_some() {
-                    buf.push_str(" t");
+                    *buf += " t";
                 }
                 if def.values.is_some() {
-                    buf.push_str(" v");
+                    *buf += " v";
                 }
                 if def.macros.is_some() {
-                    buf.push_str(" m");
+                    *buf += " m";
                 }
                 if def.is_none() {
-                    buf.push_str(" _");
+                    *buf += " _";
                 }
 
-                buf.push_str("\n");
+                *buf += "\n";
             }
 
             for (name, child) in map.modules[module].children.iter() {
-                let path = format!("{}::{}", path, name);
-                buf.push('\n');
+                let path = &format!("{}::{}", path, name);
                 go(buf, map, &path, *child);
             }
         }
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 5298dbecf9..78d0bc43bc 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -54,7 +54,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
         self.db.struct_datum(self.krate, struct_id)
     }
     fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr {
-        rust_ir::AdtRepr { repr_c: false, repr_packed: false }
+        unreachable!()
     }
     fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
         self.db.impl_datum(self.krate, impl_id)
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs
index 68ac05e4ca..f3a5e95735 100644
--- a/crates/ra_ide/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
@@ -63,7 +63,7 @@ pub use crate::completion::{
 // There also snippet completions:
 //
 // .Expressions
-// - `pd` -> `eprintln!(" = {:?}", );`
+// - `pd` -> `eprintln!(" = {:?}", );")`
 // - `ppd` -> `eprintln!(" = {:#?}", );`
 //
 // .Items
diff --git a/crates/ra_project_model/src/project_json.rs b/crates/ra_project_model/src/project_json.rs
index 778cc84ef9..b962279496 100644
--- a/crates/ra_project_model/src/project_json.rs
+++ b/crates/ra_project_model/src/project_json.rs
@@ -34,7 +34,6 @@ pub struct Crate {
     pub(crate) target: Option<String>,
     pub(crate) out_dir: Option<AbsPathBuf>,
     pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>,
-    pub(crate) is_workspace_member: bool,
 }
 
 impl ProjectJson {
@@ -44,42 +43,32 @@ impl ProjectJson {
             crates: data
                 .crates
                 .into_iter()
-                .map(|crate_data| {
-                    let is_workspace_member = crate_data.is_workspace_member.unwrap_or_else(|| {
-                        crate_data.root_module.is_relative()
-                            && !crate_data.root_module.starts_with("..")
-                            || crate_data.root_module.starts_with(base)
-                    });
-                    Crate {
-                        root_module: base.join(crate_data.root_module),
-                        edition: crate_data.edition.into(),
-                        deps: crate_data
-                            .deps
-                            .into_iter()
-                            .map(|dep_data| Dependency {
-                                crate_id: CrateId(dep_data.krate as u32),
-                                name: dep_data.name,
-                            })
-                            .collect::<Vec<_>>(),
-                        cfg: {
-                            let mut cfg = CfgOptions::default();
-                            for entry in &crate_data.cfg {
-                                match split_delim(entry, '=') {
-                                    Some((key, value)) => {
-                                        cfg.insert_key_value(key.into(), value.into());
-                                    }
-                                    None => cfg.insert_atom(entry.into()),
+                .map(|crate_data| Crate {
+                    root_module: base.join(crate_data.root_module),
+                    edition: crate_data.edition.into(),
+                    deps: crate_data
+                        .deps
+                        .into_iter()
+                        .map(|dep_data| Dependency {
+                            crate_id: CrateId(dep_data.krate as u32),
+                            name: dep_data.name,
+                        })
+                        .collect::<Vec<_>>(),
+                    cfg: {
+                        let mut cfg = CfgOptions::default();
+                        for entry in &crate_data.cfg {
+                            match split_delim(entry, '=') {
+                                Some((key, value)) => {
+                                    cfg.insert_key_value(key.into(), value.into());
                                 }
+                                None => cfg.insert_atom(entry.into()),
                             }
-                            cfg
-                        },
-                        target: crate_data.target,
-                        out_dir: crate_data.out_dir.map(|it| base.join(it)),
-                        proc_macro_dylib_path: crate_data
-                            .proc_macro_dylib_path
-                            .map(|it| base.join(it)),
-                        is_workspace_member,
-                    }
+                        }
+                        cfg
+                    },
+                    target: crate_data.target,
+                    out_dir: crate_data.out_dir.map(|it| base.join(it)),
+                    proc_macro_dylib_path: crate_data.proc_macro_dylib_path.map(|it| base.join(it)),
                 })
                 .collect::<Vec<_>>(),
         }
@@ -102,7 +91,6 @@ struct CrateData {
     target: Option<String>,
     out_dir: Option<PathBuf>,
     proc_macro_dylib_path: Option<PathBuf>,
-    is_workspace_member: Option<bool>,
 }
 
 #[derive(Deserialize)]
diff --git a/crates/vfs/src/loader.rs b/crates/vfs/src/loader.rs
index 04e257f53f..9c6e4b6a7d 100644
--- a/crates/vfs/src/loader.rs
+++ b/crates/vfs/src/loader.rs
@@ -83,11 +83,11 @@ impl Directories {
         self.includes_path(path)
     }
     fn includes_path(&self, path: &AbsPath) -> bool {
-        let mut include: Option<&AbsPathBuf> = None;
+        let mut include = None;
         for incl in &self.include {
-            if path.starts_with(incl) {
+            if is_prefix(incl, path) {
                 include = Some(match include {
-                    Some(prev) if prev.starts_with(incl) => prev,
+                    Some(prev) if is_prefix(incl, prev) => prev,
                     _ => incl,
                 })
             }
@@ -97,11 +97,15 @@ impl Directories {
             None => return false,
         };
         for excl in &self.exclude {
-            if path.starts_with(excl) && excl.starts_with(include) {
+            if is_prefix(excl, path) && is_prefix(include, excl) {
                 return false;
             }
         }
-        true
+        return true;
+
+        fn is_prefix(short: &AbsPath, long: &AbsPath) -> bool {
+            long.strip_prefix(short).is_some()
+        }
     }
 }
 


Test patch:
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 205d3528be..02dca80c25 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -21,7 +21,7 @@ fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
 fn check(ra_fixture: &str, expect: Expect) {
     let db = TestDB::with_files(ra_fixture);
     let krate = db.crate_graph().iter().next().unwrap();
-    let actual = db.crate_def_map(krate).dump();
+    let actual = db.crate_def_map(krate).dump() + "\n";
     expect.assert_eq(&actual);
 }
 
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index c972bf8450..59a21092ec 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -10,6 +10,7 @@ mod display_source_code;
 
 use std::sync::Arc;
 
+use expect::Expect;
 use hir_def::{
     body::{BodySourceMap, SyntheticSyntax},
     child_by_source::ChildBySource,
@@ -344,3 +345,15 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() {
         assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events)
     }
 }
+
+fn check_infer(ra_fixture: &str, expect: Expect) {
+    let mut actual = infer(ra_fixture);
+    actual.push('\n');
+    expect.assert_eq(&actual);
+}
+
+fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
+    let mut actual = infer_with_mismatches(ra_fixture, true);
+    actual.push('\n');
+    expect.assert_eq(&actual);
+}
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index d7fb6a962e..17efd75cb6 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -1,345 +1,381 @@
-use insta::assert_snapshot;
+use expect::expect;
 use test_utils::mark;
 
-use super::infer_with_mismatches;
-
-// Infer with some common definitions and impls.
-fn infer(source: &str) -> String {
-    let defs = r#"
-        #[lang = "sized"]
-        pub trait Sized {}
-        #[lang = "unsize"]
-        pub trait Unsize<T: ?Sized> {}
-        #[lang = "coerce_unsized"]
-        pub trait CoerceUnsized<T> {}
-
-        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
-        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
-    "#;
-
-    // Append to the end to keep positions unchanged.
-    super::infer(&format!("{}{}", source, defs))
-}
+use super::{check_infer, check_infer_with_mismatches};
 
 #[test]
 fn infer_block_expr_type_mismatch() {
-    assert_snapshot!(
-        infer(r#"
-fn test() {
-    let a: i32 = { 1i64 };
-}
-"#),
-        @r###"
-    10..40 '{     ...4 }; }': ()
-    20..21 'a': i32
-    29..37 '{ 1i64 }': i64
-    31..35 '1i64': i64
-    "###);
+    check_infer(
+        r"
+        fn test() {
+            let a: i32 = { 1i64 };
+        }
+        ",
+        expect![[r"
+            10..40 '{     ...4 }; }': ()
+            20..21 'a': i32
+            29..37 '{ 1i64 }': i64
+            31..35 '1i64': i64
+        "]],
+    );
 }
 
 #[test]
 fn coerce_places() {
-    assert_snapshot!(
-        infer(r#"
-struct S<T> { a: T }
+    check_infer(
+        r#"
+        struct S<T> { a: T }
 
-fn f<T>(_: &[T]) -> T { loop {} }
-fn g<T>(_: S<&[T]>) -> T { loop {} }
+        fn f<T>(_: &[T]) -> T { loop {} }
+        fn g<T>(_: S<&[T]>) -> T { loop {} }
 
-fn gen<T>() -> *mut [T; 2] { loop {} }
-fn test1<U>() -> *mut [U] {
-    gen()
-}
+        fn gen<T>() -> *mut [T; 2] { loop {} }
+        fn test1<U>() -> *mut [U] {
+            gen()
+        }
 
-fn test2() {
-    let arr: &[u8; 1] = &[1];
+        fn test2() {
+            let arr: &[u8; 1] = &[1];
 
-    let a: &[_] = arr;
-    let b = f(arr);
-    let c: &[_] = { arr };
-    let d = g(S { a: arr });
-    let e: [&[_]; 1] = [arr];
-    let f: [&[_]; 2] = [arr; 2];
-    let g: (&[_], &[_]) = (arr, arr);
-}
-"#),
-        @r###"
-    30..31 '_': &[T]
-    44..55 '{ loop {} }': T
-    46..53 'loop {}': !
-    51..53 '{}': ()
-    64..65 '_': S<&[T]>
-    81..92 '{ loop {} }': T
-    83..90 'loop {}': !
-    88..90 '{}': ()
-    121..132 '{ loop {} }': *mut [T; _]
-    123..130 'loop {}': !
-    128..130 '{}': ()
-    159..172 '{     gen() }': *mut [U]
-    165..168 'gen': fn gen<U>() -> *mut [U; _]
-    165..170 'gen()': *mut [U; _]
-    185..419 '{     ...rr); }': ()
-    195..198 'arr': &[u8; _]
-    211..215 '&[1]': &[u8; _]
-    212..215 '[1]': [u8; _]
-    213..214 '1': u8
-    226..227 'a': &[u8]
-    236..239 'arr': &[u8; _]
-    249..250 'b': u8
-    253..254 'f': fn f<u8>(&[u8]) -> u8
-    253..259 'f(arr)': u8
-    255..258 'arr': &[u8; _]
-    269..270 'c': &[u8]
-    279..286 '{ arr }': &[u8]
-    281..284 'arr': &[u8; _]
-    296..297 'd': u8
-    300..301 'g': fn g<u8>(S<&[u8]>) -> u8
-    300..315 'g(S { a: arr })': u8
-    302..314 'S { a: arr }': S<&[u8]>
-    309..312 'arr': &[u8; _]
-    325..326 'e': [&[u8]; _]
-    340..345 '[arr]': [&[u8]; _]
-    341..344 'arr': &[u8; _]
-    355..356 'f': [&[u8]; _]
-    370..378 '[arr; 2]': [&[u8]; _]
-    371..374 'arr': &[u8; _]
-    376..377 '2': usize
-    388..389 'g': (&[u8], &[u8])
-    406..416 '(arr, arr)': (&[u8], &[u8])
-    407..410 'arr': &[u8; _]
-    412..415 'arr': &[u8; _]
-    "###
+            let a: &[_] = arr;
+            let b = f(arr);
+            let c: &[_] = { arr };
+            let d = g(S { a: arr });
+            let e: [&[_]; 1] = [arr];
+            let f: [&[_]; 2] = [arr; 2];
+            let g: (&[_], &[_]) = (arr, arr);
+        }
+
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T: ?Sized> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+        "#,
+        expect![[r"
+            30..31 '_': &[T]
+            44..55 '{ loop {} }': T
+            46..53 'loop {}': !
+            51..53 '{}': ()
+            64..65 '_': S<&[T]>
+            81..92 '{ loop {} }': T
+            83..90 'loop {}': !
+            88..90 '{}': ()
+            121..132 '{ loop {} }': *mut [T; _]
+            123..130 'loop {}': !
+            128..130 '{}': ()
+            159..172 '{     gen() }': *mut [U]
+            165..168 'gen': fn gen<U>() -> *mut [U; _]
+            165..170 'gen()': *mut [U; _]
+            185..419 '{     ...rr); }': ()
+            195..198 'arr': &[u8; _]
+            211..215 '&[1]': &[u8; _]
+            212..215 '[1]': [u8; _]
+            213..214 '1': u8
+            226..227 'a': &[u8]
+            236..239 'arr': &[u8; _]
+            249..250 'b': u8
+            253..254 'f': fn f<u8>(&[u8]) -> u8
+            253..259 'f(arr)': u8
+            255..258 'arr': &[u8; _]
+            269..270 'c': &[u8]
+            279..286 '{ arr }': &[u8]
+            281..284 'arr': &[u8; _]
+            296..297 'd': u8
+            300..301 'g': fn g<u8>(S<&[u8]>) -> u8
+            300..315 'g(S { a: arr })': u8
+            302..314 'S { a: arr }': S<&[u8]>
+            309..312 'arr': &[u8; _]
+            325..326 'e': [&[u8]; _]
+            340..345 '[arr]': [&[u8]; _]
+            341..344 'arr': &[u8; _]
+            355..356 'f': [&[u8]; _]
+            370..378 '[arr; 2]': [&[u8]; _]
+            371..374 'arr': &[u8; _]
+            376..377 '2': usize
+            388..389 'g': (&[u8], &[u8])
+            406..416 '(arr, arr)': (&[u8], &[u8])
+            407..410 'arr': &[u8; _]
+            412..415 'arr': &[u8; _]
+        "]],
     );
 }
 
 #[test]
 fn infer_let_stmt_coerce() {
-    assert_snapshot!(
-        infer(r#"
-fn test() {
-    let x: &[isize] = &[1];
-    let x: *const [isize] = &[1];
-}
-"#),
-        @r###"
-    10..75 '{     ...[1]; }': ()
-    20..21 'x': &[isize]
-    34..38 '&[1]': &[isize; _]
-    35..38 '[1]': [isize; _]
-    36..37 '1': isize
-    48..49 'x': *const [isize]
-    68..72 '&[1]': &[isize; _]
-    69..72 '[1]': [isize; _]
-    70..71 '1': isize
-    "###);
+    check_infer(
+        r"
+        fn test() {
+            let x: &[isize] = &[1];
+            let x: *const [isize] = &[1];
+        }
+        ",
+        expect![[r"
+            10..75 '{     ...[1]; }': ()
+            20..21 'x': &[isize]
+            34..38 '&[1]': &[isize; _]
+            35..38 '[1]': [isize; _]
+            36..37 '1': isize
+            48..49 'x': *const [isize]
+            68..72 '&[1]': &[isize; _]
+            69..72 '[1]': [isize; _]
+            70..71 '1': isize
+        "]],
+    );
 }
 
 #[test]
 fn infer_custom_coerce_unsized() {
-    assert_snapshot!(
-        infer(r#"
-struct A<T: ?Sized>(*const T);
-struct B<T: ?Sized>(*const T);
-struct C<T: ?Sized> { inner: *const T }
-
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
-
-fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
-fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
-fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
-
-fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
-    let d = foo1(a);
-    let e = foo2(b);
-    let f = foo3(c);
-}
-"#),
-        @r###"
-    257..258 'x': A<[T]>
-    278..283 '{ x }': A<[T]>
-    280..281 'x': A<[T]>
-    295..296 'x': B<[T]>
-    316..321 '{ x }': B<[T]>
-    318..319 'x': B<[T]>
-    333..334 'x': C<[T]>
-    354..359 '{ x }': C<[T]>
-    356..357 'x': C<[T]>
-    369..370 'a': A<[u8; _]>
-    384..385 'b': B<[u8; _]>
-    399..400 'c': C<[u8; _]>
-    414..480 '{     ...(c); }': ()
-    424..425 'd': A<[{unknown}]>
-    428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
-    428..435 'foo1(a)': A<[{unknown}]>
-    433..434 'a': A<[u8; _]>
-    445..446 'e': B<[u8]>
-    449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
-    449..456 'foo2(b)': B<[u8]>
-    454..455 'b': B<[u8; _]>
-    466..467 'f': C<[u8]>
-    470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
-    470..477 'foo3(c)': C<[u8]>
-    475..476 'c': C<[u8; _]>
-    "###
+    check_infer(
+        r#"
+        struct A<T: ?Sized>(*const T);
+        struct B<T: ?Sized>(*const T);
+        struct C<T: ?Sized> { inner: *const T }
+
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
+
+        fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
+        fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
+        fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
+
+        fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
+            let d = foo1(a);
+            let e = foo2(b);
+            let f = foo3(c);
+        }
+
+
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T: ?Sized> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+        "#,
+        expect![[r"
+            257..258 'x': A<[T]>
+            278..283 '{ x }': A<[T]>
+            280..281 'x': A<[T]>
+            295..296 'x': B<[T]>
+            316..321 '{ x }': B<[T]>
+            318..319 'x': B<[T]>
+            333..334 'x': C<[T]>
+            354..359 '{ x }': C<[T]>
+            356..357 'x': C<[T]>
+            369..370 'a': A<[u8; _]>
+            384..385 'b': B<[u8; _]>
+            399..400 'c': C<[u8; _]>
+            414..480 '{     ...(c); }': ()
+            424..425 'd': A<[{unknown}]>
+            428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
+            428..435 'foo1(a)': A<[{unknown}]>
+            433..434 'a': A<[u8; _]>
+            445..446 'e': B<[u8]>
+            449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
+            449..456 'foo2(b)': B<[u8]>
+            454..455 'b': B<[u8; _]>
+            466..467 'f': C<[u8]>
+            470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
+            470..477 'foo3(c)': C<[u8]>
+            475..476 'c': C<[u8; _]>
+        "]],
     );
 }
 
 #[test]
 fn infer_if_coerce() {
-    assert_snapshot!(
-        infer(r#"
-fn foo<T>(x: &[T]) -> &[T] { loop {} }
-fn test() {
-    let x = if true {
-        foo(&[1])
-    } else {
-        &[1]
-    };
-}
-"#),
-        @r###"
-    10..11 'x': &[T]
-    27..38 '{ loop {} }': &[T]
-    29..36 'loop {}': !
-    34..36 '{}': ()
-    49..125 '{     ...  }; }': ()
-    59..60 'x': &[i32]
-    63..122 'if tru...     }': &[i32]
-    66..70 'true': bool
-    71..96 '{     ...     }': &[i32]
-    81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
-    81..90 'foo(&[1])': &[i32]
-    85..89 '&[1]': &[i32; _]
-    86..89 '[1]': [i32; _]
-    87..88 '1': i32
-    102..122 '{     ...     }': &[i32; _]
-    112..116 '&[1]': &[i32; _]
-    113..116 '[1]': [i32; _]
-    114..115 '1': i32
-    "###
+    check_infer(
+        r#"
+        fn foo<T>(x: &[T]) -> &[T] { loop {} }
+        fn test() {
+            let x = if true {
+                foo(&[1])
+            } else {
+                &[1]
+            };
+        }
+
+
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T: ?Sized> {}
+        "#,
+        expect![[r"
+            10..11 'x': &[T]
+            27..38 '{ loop {} }': &[T]
+            29..36 'loop {}': !
+            34..36 '{}': ()
+            49..125 '{     ...  }; }': ()
+            59..60 'x': &[i32]
+            63..122 'if tru...     }': &[i32]
+            66..70 'true': bool
+            71..96 '{     ...     }': &[i32]
+            81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
+            81..90 'foo(&[1])': &[i32]
+            85..89 '&[1]': &[i32; _]
+            86..89 '[1]': [i32; _]
+            87..88 '1': i32
+            102..122 '{     ...     }': &[i32; _]
+            112..116 '&[1]': &[i32; _]
+            113..116 '[1]': [i32; _]
+            114..115 '1': i32
+        "]],
     );
 }
 
 #[test]
 fn infer_if_else_coerce() {
-    assert_snapshot!(
-        infer(r#"
-fn foo<T>(x: &[T]) -> &[T] { loop {} }
-fn test() {
-    let x = if true {
-        &[1]
-    } else {
-        foo(&[1])
-    };
-}
-"#),
-        @r###"
-    10..11 'x': &[T]
-    27..38 '{ loop {} }': &[T]
-    29..36 'loop {}': !
-    34..36 '{}': ()
-    49..125 '{     ...  }; }': ()
-    59..60 'x': &[i32]
-    63..122 'if tru...     }': &[i32]
-    66..70 'true': bool
-    71..91 '{     ...     }': &[i32; _]
-    81..85 '&[1]': &[i32; _]
-    82..85 '[1]': [i32; _]
-    83..84 '1': i32
-    97..122 '{     ...     }': &[i32]
-    107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
-    107..116 'foo(&[1])': &[i32]
-    111..115 '&[1]': &[i32; _]
-    112..115 '[1]': [i32; _]
-    113..114 '1': i32
-    "###
-    );
+    check_infer(
+        r#"
+        fn foo<T>(x: &[T]) -> &[T] { loop {} }
+        fn test() {
+            let x = if true {
+                &[1]
+            } else {
+                foo(&[1])
+            };
+        }
+
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T: ?Sized> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+        "#,
+        expect![[r"
+            10..11 'x': &[T]
+            27..38 '{ loop {} }': &[T]
+            29..36 'loop {}': !
+            34..36 '{}': ()
+            49..125 '{     ...  }; }': ()
+            59..60 'x': &[i32]
+            63..122 'if tru...     }': &[i32]
+            66..70 'true': bool
+            71..91 '{     ...     }': &[i32; _]
+            81..85 '&[1]': &[i32; _]
+            82..85 '[1]': [i32; _]
+            83..84 '1': i32
+            97..122 '{     ...     }': &[i32]
+            107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
+            107..116 'foo(&[1])': &[i32]
+            111..115 '&[1]': &[i32; _]
+            112..115 '[1]': [i32; _]
+            113..114 '1': i32
+        "]],
+    )
 }
 
 #[test]
 fn infer_match_first_coerce() {
-    assert_snapshot!(
-        infer(r#"
-fn foo<T>(x: &[T]) -> &[T] { loop {} }
-fn test(i: i32) {
-    let x = match i {
-        2 => foo(&[2]),
-        1 => &[1],
-        _ => &[3],
-    };
-}
-"#),
-        @r###"
-    10..11 'x': &[T]
-    27..38 '{ loop {} }': &[T]
-    29..36 'loop {}': !
-    34..36 '{}': ()
-    47..48 'i': i32
-    55..149 '{     ...  }; }': ()
-    65..66 'x': &[i32]
-    69..146 'match ...     }': &[i32]
-    75..76 'i': i32
-    87..88 '2': i32
-    87..88 '2': i32
-    92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
-    92..101 'foo(&[2])': &[i32]
-    96..100 '&[2]': &[i32; _]
-    97..100 '[2]': [i32; _]
-    98..99 '2': i32
-    111..112 '1': i32
-    111..112 '1': i32
-    116..120 '&[1]': &[i32; _]
-    117..120 '[1]': [i32; _]
-    118..119 '1': i32
-    130..131 '_': i32
-    135..139 '&[3]': &[i32; _]
-    136..139 '[3]': [i32; _]
-    137..138 '3': i32
-    "###
+    check_infer(
+        r#"
+        fn foo<T>(x: &[T]) -> &[T] { loop {} }
+        fn test(i: i32) {
+            let x = match i {
+                2 => foo(&[2]),
+                1 => &[1],
+                _ => &[3],
+            };
+        }
+
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T: ?Sized> {}
+        "#,
+        expect![[r"
+            10..11 'x': &[T]
+            27..38 '{ loop {} }': &[T]
+            29..36 'loop {}': !
+            34..36 '{}': ()
+            47..48 'i': i32
+            55..149 '{     ...  }; }': ()
+            65..66 'x': &[i32]
+            69..146 'match ...     }': &[i32]
+            75..76 'i': i32
+            87..88 '2': i32
+            87..88 '2': i32
+            92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
+            92..101 'foo(&[2])': &[i32]
+            96..100 '&[2]': &[i32; _]
+            97..100 '[2]': [i32; _]
+            98..99 '2': i32
+            111..112 '1': i32
+            111..112 '1': i32
+            116..120 '&[1]': &[i32; _]
+            117..120 '[1]': [i32; _]
+            118..119 '1': i32
+            130..131 '_': i32
+            135..139 '&[3]': &[i32; _]
+            136..139 '[3]': [i32; _]
+            137..138 '3': i32
+    "]],
     );
 }
 
 #[test]
 fn infer_match_second_coerce() {
-    assert_snapshot!(
-        infer(r#"
-fn foo<T>(x: &[T]) -> &[T] { loop {} }
-fn test(i: i32) {
-    let x = match i {
-        1 => &[1],
-        2 => foo(&[2]),
-        _ => &[3],
-    };
-}
-"#),
-        @r###"
-    10..11 'x': &[T]
-    27..38 '{ loop {} }': &[T]
-    29..36 'loop {}': !
-    34..36 '{}': ()
-    47..48 'i': i32
-    55..149 '{     ...  }; }': ()
-    65..66 'x': &[i32]
-    69..146 'match ...     }': &[i32]
-    75..76 'i': i32
-    87..88 '1': i32
-    87..88 '1': i32
-    92..96 '&[1]': &[i32; _]
-    93..96 '[1]': [i32; _]
-    94..95 '1': i32
-    106..107 '2': i32
-    106..107 '2': i32
-    111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
-    111..120 'foo(&[2])': &[i32]
-    115..119 '&[2]': &[i32; _]
-    116..119 '[2]': [i32; _]
-    117..118 '2': i32
-    130..131 '_': i32
-    135..139 '&[3]': &[i32; _]
-    136..139 '[3]': [i32; _]
-    137..138 '3': i32
-    "###
+    check_infer(
+        r#"
+        fn foo<T>(x: &[T]) -> &[T] { loop {} }
+        fn test(i: i32) {
+            let x = match i {
+                1 => &[1],
+                2 => foo(&[2]),
+                _ => &[3],
+            };
+        }
+
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T: ?Sized> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+        "#,
+        expect![[r"
+            10..11 'x': &[T]
+            27..38 '{ loop {} }': &[T]
+            29..36 'loop {}': !
+            34..36 '{}': ()
+            47..48 'i': i32
+            55..149 '{     ...  }; }': ()
+            65..66 'x': &[i32]
+            69..146 'match ...     }': &[i32]
+            75..76 'i': i32
+            87..88 '1': i32
+            87..88 '1': i32
+            92..96 '&[1]': &[i32; _]
+            93..96 '[1]': [i32; _]
+            94..95 '1': i32
+            106..107 '2': i32
+            106..107 '2': i32
+            111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
+            111..120 'foo(&[2])': &[i32]
+            115..119 '&[2]': &[i32; _]
+            116..119 '[2]': [i32; _]
+            117..118 '2': i32
+            130..131 '_': i32
+            135..139 '&[3]': &[i32; _]
+            136..139 '[3]': [i32; _]
+            137..138 '3': i32
+    "]],
     );
 }
 
@@ -347,360 +383,361 @@ fn test(i: i32) {
 fn coerce_merge_one_by_one1() {
     mark::check!(coerce_merge_fail_fallback);
 
-    assert_snapshot!(
-        infer(r#"
-fn test() {
-    let t = &mut 1;
-    let x = match 1 {
-        1 => t as *mut i32,
-        2 => t as &i32,
-        _ => t as *const i32,
-    };
-}
-"#),
-        @r###"
-    10..144 '{     ...  }; }': ()
-    20..21 't': &mut i32
-    24..30 '&mut 1': &mut i32
-    29..30 '1': i32
-    40..41 'x': *const i32
-    44..141 'match ...     }': *const i32
-    50..51 '1': i32
-    62..63 '1': i32
-    62..63 '1': i32
-    67..68 't': &mut i32
-    67..80 't as *mut i32': *mut i32
-    90..91 '2': i32
-    90..91 '2': i32
-    95..96 't': &mut i32
-    95..104 't as &i32': &i32
-    114..115 '_': i32
-    119..120 't': &mut i32
-    119..134 't as *const i32': *const i32
-    "###
+    check_infer(
+        r"
+        fn test() {
+            let t = &mut 1;
+            let x = match 1 {
+                1 => t as *mut i32,
+                2 => t as &i32,
+                _ => t as *const i32,
+            };
+        }
+        ",
+        expect![[r"
+            10..144 '{     ...  }; }': ()
+            20..21 't': &mut i32
+            24..30 '&mut 1': &mut i32
+            29..30 '1': i32
+            40..41 'x': *const i32
+            44..141 'match ...     }': *const i32
+            50..51 '1': i32
+            62..63 '1': i32
+            62..63 '1': i32
+            67..68 't': &mut i32
+            67..80 't as *mut i32': *mut i32
+            90..91 '2': i32
+            90..91 '2': i32
+            95..96 't': &mut i32
+            95..104 't as &i32': &i32
+            114..115 '_': i32
+            119..120 't': &mut i32
+            119..134 't as *const i32': *const i32
+    "]],
     );
 }
 
 #[test]
 fn return_coerce_unknown() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-fn foo() -> u32 {
-    return unknown;
-}
-"#, true),
-        @r###"
-    16..39 '{     ...own; }': u32
-    22..36 'return unknown': !
-    29..36 'unknown': u32
-    "###
+    check_infer_with_mismatches(
+        r"
+        fn foo() -> u32 {
+            return unknown;
+        }
+        ",
+        expect![[r"
+            16..39 '{     ...own; }': u32
+            22..36 'return unknown': !
+            29..36 'unknown': u32
+        "]],
     );
 }
 
 #[test]
 fn coerce_autoderef() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-struct Foo;
-fn takes_ref_foo(x: &Foo) {}
-fn test() {
-    takes_ref_foo(&Foo);
-    takes_ref_foo(&&Foo);
-    takes_ref_foo(&&&Foo);
-}
-"#, true),
-        @r###"
-    29..30 'x': &Foo
-    38..40 '{}': ()
-    51..132 '{     ...oo); }': ()
-    57..70 'takes_ref_foo': fn takes_ref_foo(&Foo)
-    57..76 'takes_...(&Foo)': ()
-    71..75 '&Foo': &Foo
-    72..75 'Foo': Foo
-    82..95 'takes_ref_foo': fn takes_ref_foo(&Foo)
-    82..102 'takes_...&&Foo)': ()
-    96..101 '&&Foo': &&Foo
-    97..101 '&Foo': &Foo
-    98..101 'Foo': Foo
-    108..121 'takes_ref_foo': fn takes_ref_foo(&Foo)
-    108..129 'takes_...&&Foo)': ()
-    122..128 '&&&Foo': &&&Foo
-    123..128 '&&Foo': &&Foo
-    124..128 '&Foo': &Foo
-    125..128 'Foo': Foo
-    "###
+    check_infer_with_mismatches(
+        r"
+        struct Foo;
+        fn takes_ref_foo(x: &Foo) {}
+        fn test() {
+            takes_ref_foo(&Foo);
+            takes_ref_foo(&&Foo);
+            takes_ref_foo(&&&Foo);
+        }
+        ",
+        expect![[r"
+            29..30 'x': &Foo
+            38..40 '{}': ()
+            51..132 '{     ...oo); }': ()
+            57..70 'takes_ref_foo': fn takes_ref_foo(&Foo)
+            57..76 'takes_...(&Foo)': ()
+            71..75 '&Foo': &Foo
+            72..75 'Foo': Foo
+            82..95 'takes_ref_foo': fn takes_ref_foo(&Foo)
+            82..102 'takes_...&&Foo)': ()
+            96..101 '&&Foo': &&Foo
+            97..101 '&Foo': &Foo
+            98..101 'Foo': Foo
+            108..121 'takes_ref_foo': fn takes_ref_foo(&Foo)
+            108..129 'takes_...&&Foo)': ()
+            122..128 '&&&Foo': &&&Foo
+            123..128 '&&Foo': &&Foo
+            124..128 '&Foo': &Foo
+            125..128 'Foo': Foo
+        "]],
     );
 }
 
 #[test]
 fn coerce_autoderef_generic() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-struct Foo;
-fn takes_ref<T>(x: &T) -> T { *x }
-fn test() {
-    takes_ref(&Foo);
-    takes_ref(&&Foo);
-    takes_ref(&&&Foo);
-}
-"#, true),
-        @r###"
-    28..29 'x': &T
-    40..46 '{ *x }': T
-    42..44 '*x': T
-    43..44 'x': &T
-    57..126 '{     ...oo); }': ()
-    63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
-    63..78 'takes_ref(&Foo)': Foo
-    73..77 '&Foo': &Foo
-    74..77 'Foo': Foo
-    84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
-    84..100 'takes_...&&Foo)': &Foo
-    94..99 '&&Foo': &&Foo
-    95..99 '&Foo': &Foo
-    96..99 'Foo': Foo
-    106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
-    106..123 'takes_...&&Foo)': &&Foo
-    116..122 '&&&Foo': &&&Foo
-    117..122 '&&Foo': &&Foo
-    118..122 '&Foo': &Foo
-    119..122 'Foo': Foo
-    "###
+    check_infer_with_mismatches(
+        r"
+        struct Foo;
+        fn takes_ref<T>(x: &T) -> T { *x }
+        fn test() {
+            takes_ref(&Foo);
+            takes_ref(&&Foo);
+            takes_ref(&&&Foo);
+        }
+        ",
+        expect![[r"
+            28..29 'x': &T
+            40..46 '{ *x }': T
+            42..44 '*x': T
+            43..44 'x': &T
+            57..126 '{     ...oo); }': ()
+            63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
+            63..78 'takes_ref(&Foo)': Foo
+            73..77 '&Foo': &Foo
+            74..77 'Foo': Foo
+            84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
+            84..100 'takes_...&&Foo)': &Foo
+            94..99 '&&Foo': &&Foo
+            95..99 '&Foo': &Foo
+            96..99 'Foo': Foo
+            106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
+            106..123 'takes_...&&Foo)': &&Foo
+            116..122 '&&&Foo': &&&Foo
+            117..122 '&&Foo': &&Foo
+            118..122 '&Foo': &Foo
+            119..122 'Foo': Foo
+        "]],
     );
 }
 
 #[test]
 fn coerce_autoderef_block() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-struct String {}
-#[lang = "deref"]
-trait Deref { type Target; }
-impl Deref for String { type Target = str; }
-fn takes_ref_str(x: &str) {}
-fn returns_string() -> String { loop {} }
-fn test() {
-    takes_ref_str(&{ returns_string() });
-}
-"#, true),
-        @r###"
-    126..127 'x': &str
-    135..137 '{}': ()
-    168..179 '{ loop {} }': String
-    170..177 'loop {}': !
-    175..177 '{}': ()
-    190..235 '{     ... }); }': ()
-    196..209 'takes_ref_str': fn takes_ref_str(&str)
-    196..232 'takes_...g() })': ()
-    210..231 '&{ ret...ng() }': &String
-    211..231 '{ retu...ng() }': String
-    213..227 'returns_string': fn returns_string() -> String
-    213..229 'return...ring()': String
-    "###
+    check_infer_with_mismatches(
+        r#"
+        struct String {}
+        #[lang = "deref"]
+        trait Deref { type Target; }
+        impl Deref for String { type Target = str; }
+        fn takes_ref_str(x: &str) {}
+        fn returns_string() -> String { loop {} }
+        fn test() {
+            takes_ref_str(&{ returns_string() });
+        }
+        "#,
+        expect![[r"
+            126..127 'x': &str
+            135..137 '{}': ()
+            168..179 '{ loop {} }': String
+            170..177 'loop {}': !
+            175..177 '{}': ()
+            190..235 '{     ... }); }': ()
+            196..209 'takes_ref_str': fn takes_ref_str(&str)
+            196..232 'takes_...g() })': ()
+            210..231 '&{ ret...ng() }': &String
+            211..231 '{ retu...ng() }': String
+            213..227 'returns_string': fn returns_string() -> String
+            213..229 'return...ring()': String
+        "]],
     );
 }
 
 #[test]
 fn closure_return_coerce() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-fn foo() {
-    let x = || {
-        if true {
-            return &1u32;
+    check_infer_with_mismatches(
+        r"
+        fn foo() {
+            let x = || {
+                if true {
+                    return &1u32;
+                }
+                &&1u32
+            };
         }
-        &&1u32
-    };
-}
-"#, true),
-        @r###"
-    9..105 '{     ...  }; }': ()
-    19..20 'x': || -> &u32
-    23..102 '|| {  ...     }': || -> &u32
-    26..102 '{     ...     }': &u32
-    36..81 'if tru...     }': ()
-    39..43 'true': bool
-    44..81 '{     ...     }': ()
-    58..70 'return &1u32': !
-    65..70 '&1u32': &u32
-    66..70 '1u32': u32
-    90..96 '&&1u32': &&u32
-    91..96 '&1u32': &u32
-    92..96 '1u32': u32
-    "###
+        ",
+        expect![[r"
+            9..105 '{     ...  }; }': ()
+            19..20 'x': || -> &u32
+            23..102 '|| {  ...     }': || -> &u32
+            26..102 '{     ...     }': &u32
+            36..81 'if tru...     }': ()
+            39..43 'true': bool
+            44..81 '{     ...     }': ()
+            58..70 'return &1u32': !
+            65..70 '&1u32': &u32
+            66..70 '1u32': u32
+            90..96 '&&1u32': &&u32
+            91..96 '&1u32': &u32
+            92..96 '1u32': u32
+        "]],
     );
 }
 
 #[test]
 fn coerce_fn_item_to_fn_ptr() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-fn foo(x: u32) -> isize { 1 }
-fn test() {
-    let f: fn(u32) -> isize = foo;
-}
-"#, true),
-        @r###"
-    7..8 'x': u32
-    24..29 '{ 1 }': isize
-    26..27 '1': isize
-    40..78 '{     ...foo; }': ()
-    50..51 'f': fn(u32) -> isize
-    72..75 'foo': fn foo(u32) -> isize
-    "###
+    check_infer_with_mismatches(
+        r"
+        fn foo(x: u32) -> isize { 1 }
+        fn test() {
+            let f: fn(u32) -> isize = foo;
+        }
+        ",
+        expect![[r"
+            7..8 'x': u32
+            24..29 '{ 1 }': isize
+            26..27 '1': isize
+            40..78 '{     ...foo; }': ()
+            50..51 'f': fn(u32) -> isize
+            72..75 'foo': fn foo(u32) -> isize
+        "]],
     );
 }
 
 #[test]
 fn coerce_fn_items_in_match_arms() {
     mark::check!(coerce_fn_reification);
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-fn foo1(x: u32) -> isize { 1 }
-fn foo2(x: u32) -> isize { 2 }
-fn foo3(x: u32) -> isize { 3 }
-fn test() {
-    let x = match 1 {
-        1 => foo1,
-        2 => foo2,
-        _ => foo3,
-    };
-}
-"#, true),
-        @r###"
-    8..9 'x': u32
-    25..30 '{ 1 }': isize
-    27..28 '1': isize
-    39..40 'x': u32
-    56..61 '{ 2 }': isize
-    58..59 '2': isize
-    70..71 'x': u32
-    87..92 '{ 3 }': isize
-    89..90 '3': isize
-    103..192 '{     ...  }; }': ()
-    113..114 'x': fn(u32) -> isize
-    117..189 'match ...     }': fn(u32) -> isize
-    123..124 '1': i32
-    135..136 '1': i32
-    135..136 '1': i32
-    140..144 'foo1': fn foo1(u32) -> isize
-    154..155 '2': i32
-    154..155 '2': i32
-    159..163 'foo2': fn foo2(u32) -> isize
-    173..174 '_': i32
-    178..182 'foo3': fn foo3(u32) -> isize
-    "###
+
+    check_infer_with_mismatches(
+        r"
+        fn foo1(x: u32) -> isize { 1 }
+        fn foo2(x: u32) -> isize { 2 }
+        fn foo3(x: u32) -> isize { 3 }
+        fn test() {
+            let x = match 1 {
+                1 => foo1,
+                2 => foo2,
+                _ => foo3,
+            };
+        }
+        ",
+        expect![[r"
+            8..9 'x': u32
+            25..30 '{ 1 }': isize
+            27..28 '1': isize
+            39..40 'x': u32
+            56..61 '{ 2 }': isize
+            58..59 '2': isize
+            70..71 'x': u32
+            87..92 '{ 3 }': isize
+            89..90 '3': isize
+            103..192 '{     ...  }; }': ()
+            113..114 'x': fn(u32) -> isize
+            117..189 'match ...     }': fn(u32) -> isize
+            123..124 '1': i32
+            135..136 '1': i32
+            135..136 '1': i32
+            140..144 'foo1': fn foo1(u32) -> isize
+            154..155 '2': i32
+            154..155 '2': i32
+            159..163 'foo2': fn foo2(u32) -> isize
+            173..174 '_': i32
+            178..182 'foo3': fn foo3(u32) -> isize
+        "]],
     );
 }
 
 #[test]
 fn coerce_closure_to_fn_ptr() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-fn test() {
-    let f: fn(u32) -> isize = |x| { 1 };
-}
-"#, true),
-        @r###"
-    10..54 '{     ...1 }; }': ()
-    20..21 'f': fn(u32) -> isize
-    42..51 '|x| { 1 }': |u32| -> isize
-    43..44 'x': u32
-    46..51 '{ 1 }': isize
-    48..49 '1': isize
-    "###
+    check_infer_with_mismatches(
+        r"
+        fn test() {
+            let f: fn(u32) -> isize = |x| { 1 };
+        }
+        ",
+        expect![[r"
+            10..54 '{     ...1 }; }': ()
+            20..21 'f': fn(u32) -> isize
+            42..51 '|x| { 1 }': |u32| -> isize
+            43..44 'x': u32
+            46..51 '{ 1 }': isize
+            48..49 '1': isize
+        "]],
     );
 }
 
 #[test]
 fn coerce_placeholder_ref() {
     // placeholders should unify, even behind references
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-struct S<T> { t: T }
-impl<TT> S<TT> {
-    fn get(&self) -> &TT {
-        &self.t
-    }
-}
-"#, true),
-        @r###"
-    50..54 'self': &S<TT>
-    63..86 '{     ...     }': &TT
-    73..80 '&self.t': &TT
-    74..78 'self': &S<TT>
-    74..80 'self.t': TT
-    "###
+    check_infer_with_mismatches(
+        r"
+        struct S<T> { t: T }
+        impl<TT> S<TT> {
+            fn get(&self) -> &TT {
+                &self.t
+            }
+        }
+        ",
+        expect![[r"
+            50..54 'self': &S<TT>
+            63..86 '{     ...     }': &TT
+            73..80 '&self.t': &TT
+            74..78 'self': &S<TT>
+            74..80 'self.t': TT
+        "]],
     );
 }
 
 #[test]
 fn coerce_unsize_array() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-#[lang = "unsize"]
-pub trait Unsize<T> {}
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
+    check_infer_with_mismatches(
+        r#"
+        #[lang = "unsize"]
+        pub trait Unsize<T> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
 
-impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
+        impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
 
-fn test() {
-    let f: &[usize] = &[1, 2, 3];
-}
-"#, true),
-        @r###"
-    161..198 '{     ... 3]; }': ()
-    171..172 'f': &[usize]
-    185..195 '&[1, 2, 3]': &[usize; _]
-    186..195 '[1, 2, 3]': [usize; _]
-    187..188 '1': usize
-    190..191 '2': usize
-    193..194 '3': usize
-    "###
+        fn test() {
+            let f: &[usize] = &[1, 2, 3];
+        }
+        "#,
+        expect![[r"
+            161..198 '{     ... 3]; }': ()
+            171..172 'f': &[usize]
+            185..195 '&[1, 2, 3]': &[usize; _]
+            186..195 '[1, 2, 3]': [usize; _]
+            187..188 '1': usize
+            190..191 '2': usize
+            193..194 '3': usize
+        "]],
     );
 }
 
 #[test]
 fn coerce_unsize_trait_object_simple() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-#[lang = "sized"]
-pub trait Sized {}
-#[lang = "unsize"]
-pub trait Unsize<T> {}
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
-
-impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
-
-trait Foo<T, U> {}
-trait Bar<U, T, X>: Foo<T, U> {}
-trait Baz<T, X>: Bar<usize, T, X> {}
-
-struct S<T, X>;
-impl<T, X> Foo<T, usize> for S<T, X> {}
-impl<T, X> Bar<usize, T, X> for S<T, X> {}
-impl<T, X> Baz<T, X> for S<T, X> {}
-
-fn test() {
-    let obj: &dyn Baz<i8, i16> = &S;
-    let obj: &dyn Bar<_, i8, i16> = &S;
-    let obj: &dyn Foo<i8, _> = &S;
-}
-"#, true),
-        @r###"
-    424..539 '{     ... &S; }': ()
-    434..437 'obj': &dyn Baz<i8, i16>
-    459..461 '&S': &S<i8, i16>
-    460..461 'S': S<i8, i16>
-    471..474 'obj': &dyn Bar<usize, i8, i16>
-    499..501 '&S': &S<i8, i16>
-    500..501 'S': S<i8, i16>
-    511..514 'obj': &dyn Foo<i8, usize>
-    534..536 '&S': &S<i8, {unknown}>
-    535..536 'S': S<i8, {unknown}>
-    "###
+    check_infer_with_mismatches(
+        r#"
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
+
+        trait Foo<T, U> {}
+        trait Bar<U, T, X>: Foo<T, U> {}
+        trait Baz<T, X>: Bar<usize, T, X> {}
+
+        struct S<T, X>;
+        impl<T, X> Foo<T, usize> for S<T, X> {}
+        impl<T, X> Bar<usize, T, X> for S<T, X> {}
+        impl<T, X> Baz<T, X> for S<T, X> {}
+
+        fn test() {
+            let obj: &dyn Baz<i8, i16> = &S;
+            let obj: &dyn Bar<_, i8, i16> = &S;
+            let obj: &dyn Foo<i8, _> = &S;
+        }
+        "#,
+        expect![[r"
+            424..539 '{     ... &S; }': ()
+            434..437 'obj': &dyn Baz<i8, i16>
+            459..461 '&S': &S<i8, i16>
+            460..461 'S': S<i8, i16>
+            471..474 'obj': &dyn Bar<usize, i8, i16>
+            499..501 '&S': &S<i8, i16>
+            500..501 'S': S<i8, i16>
+            511..514 'obj': &dyn Foo<i8, usize>
+            534..536 '&S': &S<i8, {unknown}>
+            535..536 'S': S<i8, {unknown}>
+        "]],
     );
 }
 
@@ -709,90 +746,90 @@ fn test() {
 // it. We used to support it, but Chalk doesn't.
 #[ignore]
 fn coerce_unsize_trait_object_to_trait_object() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-#[lang = "sized"]
-pub trait Sized {}
-#[lang = "unsize"]
-pub trait Unsize<T> {}
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
-
-impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
-
-trait Foo<T, U> {}
-trait Bar<U, T, X>: Foo<T, U> {}
-trait Baz<T, X>: Bar<usize, T, X> {}
-
-struct S<T, X>;
-impl<T, X> Foo<T, usize> for S<T, X> {}
-impl<T, X> Bar<usize, T, X> for S<T, X> {}
-impl<T, X> Baz<T, X> for S<T, X> {}
-
-fn test() {
-    let obj: &dyn Baz<i8, i16> = &S;
-    let obj: &dyn Bar<_, _, _> = obj;
-    let obj: &dyn Foo<_, _> = obj;
-    let obj2: &dyn Baz<i8, i16> = &S;
-    let _: &dyn Foo<_, _> = obj2;
-}
-"#, true),
-        @r###"
-    424..609 '{     ...bj2; }': ()
-    434..437 'obj': &dyn Baz<i8, i16>
-    459..461 '&S': &S<i8, i16>
-    460..461 'S': S<i8, i16>
-    471..474 'obj': &dyn Bar<usize, i8, i16>
-    496..499 'obj': &dyn Baz<i8, i16>
-    509..512 'obj': &dyn Foo<i8, usize>
-    531..534 'obj': &dyn Bar<usize, i8, i16>
-    544..548 'obj2': &dyn Baz<i8, i16>
-    570..572 '&S': &S<i8, i16>
-    571..572 'S': S<i8, i16>
-    582..583 '_': &dyn Foo<i8, usize>
-    602..606 'obj2': &dyn Baz<i8, i16>
-    "###
+    check_infer_with_mismatches(
+        r#"
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
+
+        trait Foo<T, U> {}
+        trait Bar<U, T, X>: Foo<T, U> {}
+        trait Baz<T, X>: Bar<usize, T, X> {}
+
+        struct S<T, X>;
+        impl<T, X> Foo<T, usize> for S<T, X> {}
+        impl<T, X> Bar<usize, T, X> for S<T, X> {}
+        impl<T, X> Baz<T, X> for S<T, X> {}
+
+        fn test() {
+            let obj: &dyn Baz<i8, i16> = &S;
+            let obj: &dyn Bar<_, _, _> = obj;
+            let obj: &dyn Foo<_, _> = obj;
+            let obj2: &dyn Baz<i8, i16> = &S;
+            let _: &dyn Foo<_, _> = obj2;
+        }
+        "#,
+        expect![[r"
+            424..609 '{     ...bj2; }': ()
+            434..437 'obj': &dyn Baz<i8, i16>
+            459..461 '&S': &S<i8, i16>
+            460..461 'S': S<i8, i16>
+            471..474 'obj': &dyn Bar<usize, i8, i16>
+            496..499 'obj': &dyn Baz<i8, i16>
+            509..512 'obj': &dyn Foo<i8, usize>
+            531..534 'obj': &dyn Bar<usize, i8, i16>
+            544..548 'obj2': &dyn Baz<i8, i16>
+            570..572 '&S': &S<i8, i16>
+            571..572 'S': S<i8, i16>
+            582..583 '_': &dyn Foo<i8, usize>
+            602..606 'obj2': &dyn Baz<i8, i16>
+        "]],
     );
 }
 
 #[test]
 fn coerce_unsize_super_trait_cycle() {
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-#[lang = "sized"]
-pub trait Sized {}
-#[lang = "unsize"]
-pub trait Unsize<T> {}
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
-
-impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
-
-trait A {}
-trait B: C + A {}
-trait C: B {}
-trait D: C
-
-struct S;
-impl A for S {}
-impl B for S {}
-impl C for S {}
-impl D for S {}
-
-fn test() {
-    let obj: &dyn D = &S;
-    let obj: &dyn A = &S;
-}
-"#, true),
-        @r###"
-    328..383 '{     ... &S; }': ()
-    338..341 'obj': &dyn D
-    352..354 '&S': &S
-    353..354 'S': S
-    364..367 'obj': &dyn A
-    378..380 '&S': &S
-    379..380 'S': S
-    "###
+    check_infer_with_mismatches(
+        r#"
+        #[lang = "sized"]
+        pub trait Sized {}
+        #[lang = "unsize"]
+        pub trait Unsize<T> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
+
+        impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
+
+        trait A {}
+        trait B: C + A {}
+        trait C: B {}
+        trait D: C
+
+        struct S;
+        impl A for S {}
+        impl B for S {}
+        impl C for S {}
+        impl D for S {}
+
+        fn test() {
+            let obj: &dyn D = &S;
+            let obj: &dyn A = &S;
+        }
+        "#,
+        expect![[r"
+            328..383 '{     ... &S; }': ()
+            338..341 'obj': &dyn D
+            352..354 '&S': &S
+            353..354 'S': S
+            364..367 'obj': &dyn A
+            378..380 '&S': &S
+            379..380 'S': S
+        "]],
     );
 }
 
@@ -801,24 +838,24 @@ fn test() {
 fn coerce_unsize_generic() {
     // FIXME: Implement this
     // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
-    assert_snapshot!(
-        infer_with_mismatches(r#"
-#[lang = "unsize"]
-pub trait Unsize<T> {}
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
+    check_infer_with_mismatches(
+        r#"
+        #[lang = "unsize"]
+        pub trait Unsize<T> {}
+        #[lang = "coerce_unsized"]
+        pub trait CoerceUnsized<T> {}
 
-impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
+        impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
 
-struct Foo<T> { t: T };
-struct Bar<T>(Foo<T>);
+        struct Foo<T> { t: T };
+        struct Bar<T>(Foo<T>);
 
-fn test() {
-    let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
-    let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
-}
-"#, true),
-        @r###"
-    "###
+        fn test() {
+            let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
+            let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
+        }
+        "#,
+        expect![[r"
+        "]],
     );
 }
diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs
index 64d421d405..49538b572d 100644
--- a/crates/ra_hir_ty/src/tests/never_type.rs
+++ b/crates/ra_hir_ty/src/tests/never_type.rs
@@ -1,6 +1,6 @@
-use insta::assert_snapshot;
+use expect::expect;
 
-use super::{check_types, infer_with_mismatches};
+use super::{check_infer_with_mismatches, check_types};
 
 #[test]
 fn infer_never1() {
@@ -240,173 +240,170 @@ fn test(a: i32) {
 
 #[test]
 fn diverging_expression_1() {
-    let t = infer_with_mismatches(
-        r#"
-//- /main.rs
-fn test1() {
-    let x: u32 = return;
-}
-fn test2() {
-    let x: u32 = { return; };
-}
-fn test3() {
-    let x: u32 = loop {};
-}
-fn test4() {
-    let x: u32 = { loop {} };
-}
-fn test5() {
-    let x: u32 = { if true { loop {}; } else { loop {}; } };
-}
-fn test6() {
-    let x: u32 = { let y: u32 = { loop {}; }; };
-}
-"#,
-        true,
+    check_infer_with_mismatches(
+        r"
+        //- /main.rs
+        fn test1() {
+            let x: u32 = return;
+        }
+        fn test2() {
+            let x: u32 = { return; };
+        }
+        fn test3() {
+            let x: u32 = loop {};
+        }
+        fn test4() {
+            let x: u32 = { loop {} };
+        }
+        fn test5() {
+            let x: u32 = { if true { loop {}; } else { loop {}; } };
+        }
+        fn test6() {
+            let x: u32 = { let y: u32 = { loop {}; }; };
+        }
+        ",
+        expect![[r"
+            11..39 '{     ...urn; }': ()
+            21..22 'x': u32
+            30..36 'return': !
+            51..84 '{     ...; }; }': ()
+            61..62 'x': u32
+            70..81 '{ return; }': u32
+            72..78 'return': !
+            96..125 '{     ... {}; }': ()
+            106..107 'x': u32
+            115..122 'loop {}': !
+            120..122 '{}': ()
+            137..170 '{     ...} }; }': ()
+            147..148 'x': u32
+            156..167 '{ loop {} }': u32
+            158..165 'loop {}': !
+            163..165 '{}': ()
+            182..246 '{     ...} }; }': ()
+            192..193 'x': u32
+            201..243 '{ if t...}; } }': u32
+            203..241 'if tru... {}; }': u32
+            206..210 'true': bool
+            211..223 '{ loop {}; }': u32
+            213..220 'loop {}': !
+            218..220 '{}': ()
+            229..241 '{ loop {}; }': u32
+            231..238 'loop {}': !
+            236..238 '{}': ()
+            258..310 '{     ...; }; }': ()
+            268..269 'x': u32
+            277..307 '{ let ...; }; }': u32
+            283..284 'y': u32
+            292..304 '{ loop {}; }': u32
+            294..301 'loop {}': !
+            299..301 '{}': ()
+        "]],
     );
-    assert_snapshot!(t, @r###"
-    11..39 '{     ...urn; }': ()
-    21..22 'x': u32
-    30..36 'return': !
-    51..84 '{     ...; }; }': ()
-    61..62 'x': u32
-    70..81 '{ return; }': u32
-    72..78 'return': !
-    96..125 '{     ... {}; }': ()
-    106..107 'x': u32
-    115..122 'loop {}': !
-    120..122 '{}': ()
-    137..170 '{     ...} }; }': ()
-    147..148 'x': u32
-    156..167 '{ loop {} }': u32
-    158..165 'loop {}': !
-    163..165 '{}': ()
-    182..246 '{     ...} }; }': ()
-    192..193 'x': u32
-    201..243 '{ if t...}; } }': u32
-    203..241 'if tru... {}; }': u32
-    206..210 'true': bool
-    211..223 '{ loop {}; }': u32
-    213..220 'loop {}': !
-    218..220 '{}': ()
-    229..241 '{ loop {}; }': u32
-    231..238 'loop {}': !
-    236..238 '{}': ()
-    258..310 '{     ...; }; }': ()
-    268..269 'x': u32
-    277..307 '{ let ...; }; }': u32
-    283..284 'y': u32
-    292..304 '{ loop {}; }': u32
-    294..301 'loop {}': !
-    299..301 '{}': ()
-    "###);
 }
 
 #[test]
 fn diverging_expression_2() {
-    let t = infer_with_mismatches(
+    check_infer_with_mismatches(
         r#"
-//- /main.rs
-fn test1() {
-    // should give type mismatch
-    let x: u32 = { loop {}; "foo" };
-}
-"#,
-        true,
+        //- /main.rs
+        fn test1() {
+            // should give type mismatch
+            let x: u32 = { loop {}; "foo" };
+        }
+        "#,
+        expect![[r#"
+            11..84 '{     ..." }; }': ()
+            54..55 'x': u32
+            63..81 '{ loop...foo" }': &str
+            65..72 'loop {}': !
+            70..72 '{}': ()
+            74..79 '"foo"': &str
+            63..81: expected u32, got &str
+            74..79: expected u32, got &str
+        "#]],
     );
-    assert_snapshot!(t, @r###"
-    11..84 '{     ..." }; }': ()
-    54..55 'x': u32
-    63..81 '{ loop...foo" }': &str
-    65..72 'loop {}': !
-    70..72 '{}': ()
-    74..79 '"foo"': &str
-    63..81: expected u32, got &str
-    74..79: expected u32, got &str
-    "###);
 }
 
 #[test]
 fn diverging_expression_3_break() {
-    let t = infer_with_mismatches(
-        r#"
-//- /main.rs
-fn test1() {
-    // should give type mismatch
-    let x: u32 = { loop { break; } };
-}
-fn test2() {
-    // should give type mismatch
-    let x: u32 = { for a in b { break; }; };
-    // should give type mismatch as well
-    let x: u32 = { for a in b {}; };
-    // should give type mismatch as well
-    let x: u32 = { for a in b { return; }; };
-}
-fn test3() {
-    // should give type mismatch
-    let x: u32 = { while true { break; }; };
-    // should give type mismatch as well -- there's an implicit break, even if it's never hit
-    let x: u32 = { while true {}; };
-    // should give type mismatch as well
-    let x: u32 = { while true { return; }; };
-}
-"#,
-        true,
+    check_infer_with_mismatches(
+        r"
+        //- /main.rs
+        fn test1() {
+            // should give type mismatch
+            let x: u32 = { loop { break; } };
+        }
+        fn test2() {
+            // should give type mismatch
+            let x: u32 = { for a in b { break; }; };
+            // should give type mismatch as well
+            let x: u32 = { for a in b {}; };
+            // should give type mismatch as well
+            let x: u32 = { for a in b { return; }; };
+        }
+        fn test3() {
+            // should give type mismatch
+            let x: u32 = { while true { break; }; };
+            // should give type mismatch as well -- there's an implicit break, even if it's never hit
+            let x: u32 = { while true {}; };
+            // should give type mismatch as well
+            let x: u32 = { while true { return; }; };
+        }
+        ",
+        expect![[r"
+            11..85 '{     ...} }; }': ()
+            54..55 'x': u32
+            63..82 '{ loop...k; } }': ()
+            65..80 'loop { break; }': ()
+            70..80 '{ break; }': ()
+            72..77 'break': !
+            63..82: expected u32, got ()
+            65..80: expected u32, got ()
+            97..343 '{     ...; }; }': ()
+            140..141 'x': u32
+            149..175 '{ for ...; }; }': ()
+            151..172 'for a ...eak; }': ()
+            155..156 'a': {unknown}
+            160..161 'b': {unknown}
+            162..172 '{ break; }': ()
+            164..169 'break': !
+            226..227 'x': u32
+            235..253 '{ for ... {}; }': ()
+            237..250 'for a in b {}': ()
+            241..242 'a': {unknown}
+            246..247 'b': {unknown}
+            248..250 '{}': ()
+            304..305 'x': u32
+            313..340 '{ for ...; }; }': ()
+            315..337 'for a ...urn; }': ()
+            319..320 'a': {unknown}
+            324..325 'b': {unknown}
+            326..337 '{ return; }': ()
+            328..334 'return': !
+            149..175: expected u32, got ()
+            235..253: expected u32, got ()
+            313..340: expected u32, got ()
+            355..654 '{     ...; }; }': ()
+            398..399 'x': u32
+            407..433 '{ whil...; }; }': ()
+            409..430 'while ...eak; }': ()
+            415..419 'true': bool
+            420..430 '{ break; }': ()
+            422..427 'break': !
+            537..538 'x': u32
+            546..564 '{ whil... {}; }': ()
+            548..561 'while true {}': ()
+            554..558 'true': bool
+            559..561 '{}': ()
+            615..616 'x': u32
+            624..651 '{ whil...; }; }': ()
+            626..648 'while ...urn; }': ()
+            632..636 'true': bool
+            637..648 '{ return; }': ()
+            639..645 'return': !
+            407..433: expected u32, got ()
+            546..564: expected u32, got ()
+            624..651: expected u32, got ()
+        "]],
     );
-    assert_snapshot!(t, @r###"
-    11..85 '{     ...} }; }': ()
-    54..55 'x': u32
-    63..82 '{ loop...k; } }': ()
-    65..80 'loop { break; }': ()
-    70..80 '{ break; }': ()
-    72..77 'break': !
-    63..82: expected u32, got ()
-    65..80: expected u32, got ()
-    97..343 '{     ...; }; }': ()
-    140..141 'x': u32
-    149..175 '{ for ...; }; }': ()
-    151..172 'for a ...eak; }': ()
-    155..156 'a': {unknown}
-    160..161 'b': {unknown}
-    162..172 '{ break; }': ()
-    164..169 'break': !
-    226..227 'x': u32
-    235..253 '{ for ... {}; }': ()
-    237..250 'for a in b {}': ()
-    241..242 'a': {unknown}
-    246..247 'b': {unknown}
-    248..250 '{}': ()
-    304..305 'x': u32
-    313..340 '{ for ...; }; }': ()
-    315..337 'for a ...urn; }': ()
-    319..320 'a': {unknown}
-    324..325 'b': {unknown}
-    326..337 '{ return; }': ()
-    328..334 'return': !
-    149..175: expected u32, got ()
-    235..253: expected u32, got ()
-    313..340: expected u32, got ()
-    355..654 '{     ...; }; }': ()
-    398..399 'x': u32
-    407..433 '{ whil...; }; }': ()
-    409..430 'while ...eak; }': ()
-    415..419 'true': bool
-    420..430 '{ break; }': ()
-    422..427 'break': !
-    537..538 'x': u32
-    546..564 '{ whil... {}; }': ()
-    548..561 'while true {}': ()
-    554..558 'true': bool
-    559..561 '{}': ()
-    615..616 'x': u32
-    624..651 '{ whil...; }; }': ()
-    626..648 'while ...urn; }': ()
-    632..636 'true': bool
-    637..648 '{ return; }': ()
-    639..645 'return': !
-    407..433: expected u32, got ()
-    546..564: expected u32, got ()
-    624..651: expected u32, got ()
-    "###);
 }