]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests/traits.rs
Merge #9007
[rust.git] / crates / hir_ty / src / tests / traits.rs
index e185b1c0a16c7b8e27bd79fec889963dc9d7cc2f..6ad96bfe383ae60b119157c342433d00714f4ded 100644 (file)
@@ -160,6 +160,43 @@ impl<O, E> crate::ops::Try for Result<O, E> {
     );
 }
 
+#[test]
+fn infer_tryv2() {
+    check_types(
+        r#"
+//- /main.rs crate:main deps:core
+fn test() {
+    let r: Result<i32, u64> = Result::Ok(1);
+    let v = r?;
+    v;
+} //^ i32
+
+//- /core.rs crate:core
+#[prelude_import] use ops::*;
+mod ops {
+    trait Try {
+        type Output;
+        type Residual;
+    }
+}
+
+#[prelude_import] use result::*;
+mod result {
+    enum Infallible {}
+    enum Result<O, E> {
+        Ok(O),
+        Err(E)
+    }
+
+    impl<O, E> crate::ops::Try for Result<O, E> {
+        type Output = O;
+        type Error = Result<Infallible, E>;
+    }
+}
+"#,
+    );
+}
+
 #[test]
 fn infer_for_loop() {
     check_types(
@@ -187,8 +224,8 @@ trait IntoIterator {
 mod collections {
     struct Vec<T> {}
     impl<T> Vec<T> {
-        fn new() -> Self { Vec {} }
-        fn push(&mut self, t: T) { }
+        pub fn new() -> Self { Vec {} }
+        pub fn push(&mut self, t: T) { }
     }
 
     impl<T> IntoIterator for Vec<T> {
@@ -263,15 +300,14 @@ pub trait Not {
 fn infer_from_bound_1() {
     check_infer(
         r#"
-        trait Trait<T> {}
-        struct S<T>(T);
-        impl<U> Trait<U> for S<U> {}
-        fn foo<T: Trait<u32>>(t: T) {}
-        fn test() {
-            let s = S(unknown);
-            foo(s);
-        }
-        "#,
+trait Trait<T> {}
+struct S<T>(T);
+impl<U> Trait<U> for S<U> {}
+fn foo<T: Trait<u32>>(t: T) {}
+fn test() {
+    let s = S(unknown);
+    foo(s);
+}"#,
         expect![[r#"
             85..86 't': T
             91..93 '{}': ()
@@ -291,15 +327,14 @@ fn test() {
 fn infer_from_bound_2() {
     check_infer(
         r#"
-        trait Trait<T> {}
-        struct S<T>(T);
-        impl<U> Trait<U> for S<U> {}
-        fn foo<U, T: Trait<U>>(t: T) -> U {}
-        fn test() {
-            let s = S(unknown);
-            let x: u32 = foo(s);
-        }
-        "#,
+trait Trait<T> {}
+struct S<T>(T);
+impl<U> Trait<U> for S<U> {}
+fn foo<U, T: Trait<U>>(t: T) -> U {}
+fn test() {
+    let s = S(unknown);
+    let x: u32 = foo(s);
+}"#,
         expect![[r#"
             86..87 't': T
             97..99 '{}': ()
@@ -321,13 +356,12 @@ fn trait_default_method_self_bound_implements_trait() {
     cov_mark::check!(trait_self_implements_self);
     check_infer(
         r#"
-        trait Trait {
-            fn foo(&self) -> i64;
-            fn bar(&self) -> {
-                let x = self.foo();
-            }
-        }
-        "#,
+trait Trait {
+    fn foo(&self) -> i64;
+    fn bar(&self) -> {
+        let x = self.foo();
+    }
+}"#,
         expect![[r#"
             26..30 'self': &Self
             52..56 'self': &Self
@@ -343,15 +377,14 @@ fn bar(&self) -> {
 fn trait_default_method_self_bound_implements_super_trait() {
     check_infer(
         r#"
-        trait SuperTrait {
-            fn foo(&self) -> i64;
-        }
-        trait Trait: SuperTrait {
-            fn bar(&self) -> {
-                let x = self.foo();
-            }
-        }
-        "#,
+trait SuperTrait {
+    fn foo(&self) -> i64;
+}
+trait Trait: SuperTrait {
+    fn bar(&self) -> {
+        let x = self.foo();
+    }
+}"#,
         expect![[r#"
             31..35 'self': &Self
             85..89 'self': &Self
@@ -367,18 +400,17 @@ fn bar(&self) -> {
 fn infer_project_associated_type() {
     check_infer(
         r#"
-        trait Iterable {
-            type Item;
-        }
-        struct S;
-        impl Iterable for S { type Item = u32; }
-        fn test<T: Iterable>() {
-            let x: <S as Iterable>::Item = 1;
-            let y: <T as Iterable>::Item = no_matter;
-            let z: T::Item = no_matter;
-            let a: <T>::Item = no_matter;
-        }
-        "#,
+trait Iterable {
+    type Item;
+}
+struct S;
+impl Iterable for S { type Item = u32; }
+fn test<T: Iterable>() {
+    let x: <S as Iterable>::Item = 1;
+    let y: <T as Iterable>::Item = no_matter;
+    let z: T::Item = no_matter;
+    let a: <T>::Item = no_matter;
+}"#,
         expect![[r#"
             108..261 '{     ...ter; }': ()
             118..119 'x': u32
@@ -397,20 +429,19 @@ fn test<T: Iterable>() {
 fn infer_return_associated_type() {
     check_infer(
         r#"
-        trait Iterable {
-            type Item;
-        }
-        struct S;
-        impl Iterable for S { type Item = u32; }
-        fn foo1<T: Iterable>(t: T) -> T::Item {}
-        fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {}
-        fn foo3<T: Iterable>(t: T) -> <T>::Item {}
-        fn test() {
-            let x = foo1(S);
-            let y = foo2(S);
-            let z = foo3(S);
-        }
-        "#,
+trait Iterable {
+    type Item;
+}
+struct S;
+impl Iterable for S { type Item = u32; }
+fn foo1<T: Iterable>(t: T) -> T::Item {}
+fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {}
+fn foo3<T: Iterable>(t: T) -> <T>::Item {}
+fn test() {
+    let x = foo1(S);
+    let y = foo2(S);
+    let z = foo3(S);
+}"#,
         expect![[r#"
             106..107 't': T
             123..125 '{}': ()
@@ -439,13 +470,12 @@ fn test() {
 fn infer_associated_type_bound() {
     check_infer(
         r#"
-        trait Iterable {
-            type Item;
-        }
-        fn test<T: Iterable<Item=u32>>() {
-            let y: T::Item = unknown;
-        }
-        "#,
+trait Iterable {
+    type Item;
+}
+fn test<T: Iterable<Item=u32>>() {
+    let y: T::Item = unknown;
+}"#,
         expect![[r#"
             67..100 '{     ...own; }': ()
             77..78 'y': u32
@@ -458,9 +488,8 @@ fn test<T: Iterable<Item=u32>>() {
 fn infer_const_body() {
     check_infer(
         r#"
-        const A: u32 = 1 + 1;
-        static B: u64 = { let x = 1; x };
-        "#,
+const A: u32 = 1 + 1;
+static B: u64 = { let x = 1; x };"#,
         expect![[r#"
             15..16 '1': u32
             15..20 '1 + 1': u32
@@ -477,13 +506,12 @@ fn infer_const_body() {
 fn tuple_struct_fields() {
     check_infer(
         r#"
-        struct S(i32, u64);
-        fn test() -> u64 {
-            let a = S(4, 6);
-            let b = a.0;
-            a.1
-        }
-        "#,
+struct S(i32, u64);
+fn test() -> u64 {
+    let a = S(4, 6);
+    let b = a.0;
+    a.1
+}"#,
         expect![[r#"
             37..86 '{     ... a.1 }': u64
             47..48 'a': S
@@ -504,13 +532,12 @@ fn test() -> u64 {
 fn tuple_struct_with_fn() {
     check_infer(
         r#"
-        struct S(fn(u32) -> u64);
-        fn test() -> u64 {
-            let a = S(|i| 2*i);
-            let b = a.0(4);
-            a.0(2)
-        }
-        "#,
+struct S(fn(u32) -> u64);
+fn test() -> u64 {
+    let a = S(|i| 2*i);
+    let b = a.0(4);
+    a.0(2)
+}"#,
         expect![[r#"
             43..101 '{     ...0(2) }': u64
             53..54 'a': S
@@ -541,7 +568,7 @@ fn indexing_arrays() {
         expect![[r#"
             10..26 '{ &mut...[2]; }': ()
             12..23 '&mut [9][2]': &mut {unknown}
-            17..20 '[9]': [i32; _]
+            17..20 '[9]': [i32; 1]
             17..23 '[9][2]': {unknown}
             18..19 '9': i32
             21..22 '2': i32
@@ -949,27 +976,26 @@ fn test<T: ApplyL>(t: T) {
 fn argument_impl_trait() {
     check_infer_with_mismatches(
         r#"
-        trait Trait<T> {
-            fn foo(&self) -> T;
-            fn foo2(&self) -> i64;
-        }
-        fn bar(x: impl Trait<u16>) {}
-        struct S<T>(T);
-        impl<T> Trait<T> for S<T> {}
-
-        fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
-            x;
-            y;
-            let z = S(1);
-            bar(z);
-            x.foo();
-            y.foo();
-            z.foo();
-            x.foo2();
-            y.foo2();
-            z.foo2();
-        }
-        "#,
+trait Trait<T> {
+    fn foo(&self) -> T;
+    fn foo2(&self) -> i64;
+}
+fn bar(x: impl Trait<u16>) {}
+struct S<T>(T);
+impl<T> Trait<T> for S<T> {}
+
+fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
+    x;
+    y;
+    let z = S(1);
+    bar(z);
+    x.foo();
+    y.foo();
+    z.foo();
+    x.foo2();
+    y.foo2();
+    z.foo2();
+}"#,
         expect![[r#"
             29..33 'self': &Self
             54..58 'self': &Self
@@ -1007,30 +1033,29 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
 fn argument_impl_trait_type_args_1() {
     check_infer_with_mismatches(
         r#"
-        trait Trait {}
-        trait Foo {
-            // this function has an implicit Self param, an explicit type param,
-            // and an implicit impl Trait param!
-            fn bar<T>(x: impl Trait) -> T { loop {} }
-        }
-        fn foo<T>(x: impl Trait) -> T { loop {} }
-        struct S;
-        impl Trait for S {}
-        struct F;
-        impl Foo for F {}
-
-        fn test() {
-            Foo::bar(S);
-            <F as Foo>::bar(S);
-            F::bar(S);
-            Foo::bar::<u32>(S);
-            <F as Foo>::bar::<u32>(S);
-
-            foo(S);
-            foo::<u32>(S);
-            foo::<u32, i32>(S); // we should ignore the extraneous i32
-        }
-        "#,
+trait Trait {}
+trait Foo {
+    // this function has an implicit Self param, an explicit type param,
+    // and an implicit impl Trait param!
+    fn bar<T>(x: impl Trait) -> T { loop {} }
+}
+fn foo<T>(x: impl Trait) -> T { loop {} }
+struct S;
+impl Trait for S {}
+struct F;
+impl Foo for F {}
+
+fn test() {
+    Foo::bar(S);
+    <F as Foo>::bar(S);
+    F::bar(S);
+    Foo::bar::<u32>(S);
+    <F as Foo>::bar::<u32>(S);
+
+    foo(S);
+    foo::<u32>(S);
+    foo::<u32, i32>(S); // we should ignore the extraneous i32
+}"#,
         expect![[r#"
             155..156 'x': impl Trait
             175..186 '{ loop {} }': T
@@ -1073,21 +1098,20 @@ fn test() {
 fn argument_impl_trait_type_args_2() {
     check_infer_with_mismatches(
         r#"
-        trait Trait {}
-        struct S;
-        impl Trait for S {}
-        struct F<T>;
-        impl<T> F<T> {
-            fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
-        }
+trait Trait {}
+struct S;
+impl Trait for S {}
+struct F<T>;
+impl<T> F<T> {
+    fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
+}
 
-        fn test() {
-            F.foo(S);
-            F::<u32>.foo(S);
-            F::<u32>.foo::<i32>(S);
-            F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
-        }
-        "#,
+fn test() {
+    F.foo(S);
+    F::<u32>.foo(S);
+    F::<u32>.foo::<i32>(S);
+    F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
+}"#,
         expect![[r#"
             87..91 'self': F<T>
             93..94 'x': impl Trait
@@ -1115,15 +1139,14 @@ fn test() {
 fn argument_impl_trait_to_fn_pointer() {
     check_infer_with_mismatches(
         r#"
-        trait Trait {}
-        fn foo(x: impl Trait) { loop {} }
-        struct S;
-        impl Trait for S {}
+trait Trait {}
+fn foo(x: impl Trait) { loop {} }
+struct S;
+impl Trait for S {}
 
-        fn test() {
-            let f: fn(S) -> () = foo;
-        }
-        "#,
+fn test() {
+    let f: fn(S) -> () = foo;
+}"#,
         expect![[r#"
             22..23 'x': impl Trait
             37..48 '{ loop {} }': ()
@@ -1140,24 +1163,23 @@ fn test() {
 fn impl_trait() {
     check_infer(
         r#"
-        trait Trait<T> {
-            fn foo(&self) -> T;
-            fn foo2(&self) -> i64;
-        }
-        fn bar() -> impl Trait<u64> {}
+trait Trait<T> {
+    fn foo(&self) -> T;
+    fn foo2(&self) -> i64;
+}
+fn bar() -> impl Trait<u64> {}
 
-        fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
-            x;
-            y;
-            let z = bar();
-            x.foo();
-            y.foo();
-            z.foo();
-            x.foo2();
-            y.foo2();
-            z.foo2();
-        }
-        "#,
+fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
+    x;
+    y;
+    let z = bar();
+    x.foo();
+    y.foo();
+    z.foo();
+    x.foo2();
+    y.foo2();
+    z.foo2();
+}"#,
         expect![[r#"
             29..33 'self': &Self
             54..58 'self': &Self
@@ -1191,16 +1213,15 @@ fn simple_return_pos_impl_trait() {
     cov_mark::check!(lower_rpit);
     check_infer(
         r#"
-        trait Trait<T> {
-            fn foo(&self) -> T;
-        }
-        fn bar() -> impl Trait<u64> { loop {} }
+trait Trait<T> {
+    fn foo(&self) -> T;
+}
+fn bar() -> impl Trait<u64> { loop {} }
 
-        fn test() {
-            let a = bar();
-            a.foo();
-        }
-        "#,
+fn test() {
+    let a = bar();
+    a.foo();
+}"#,
         expect![[r#"
             29..33 'self': &Self
             71..82 '{ loop {} }': !
@@ -1220,25 +1241,24 @@ fn test() {
 fn more_return_pos_impl_trait() {
     check_infer(
         r#"
-        trait Iterator {
-            type Item;
-            fn next(&mut self) -> Self::Item;
-        }
-        trait Trait<T> {
-            fn foo(&self) -> T;
-        }
-        fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} }
-        fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} }
-
-        fn test() {
-            let (a, b) = bar();
-            a.next().foo();
-            b.foo();
-            let (c, d) = baz(1u128);
-            c.next().foo();
-            d.foo();
-        }
-        "#,
+trait Iterator {
+    type Item;
+    fn next(&mut self) -> Self::Item;
+}
+trait Trait<T> {
+    fn foo(&self) -> T;
+}
+fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} }
+fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} }
+
+fn test() {
+    let (a, b) = bar();
+    a.next().foo();
+    b.foo();
+    let (c, d) = baz(1u128);
+    c.next().foo();
+    d.foo();
+}"#,
         expect![[r#"
             49..53 'self': &mut Self
             101..105 'self': &Self
@@ -1279,24 +1299,23 @@ fn test() {
 fn dyn_trait() {
     check_infer(
         r#"
-        trait Trait<T> {
-            fn foo(&self) -> T;
-            fn foo2(&self) -> i64;
-        }
-        fn bar() -> dyn Trait<u64> {}
+trait Trait<T> {
+    fn foo(&self) -> T;
+    fn foo2(&self) -> i64;
+}
+fn bar() -> dyn Trait<u64> {}
 
-        fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
-            x;
-            y;
-            let z = bar();
-            x.foo();
-            y.foo();
-            z.foo();
-            x.foo2();
-            y.foo2();
-            z.foo2();
-        }
-        "#,
+fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
+    x;
+    y;
+    let z = bar();
+    x.foo();
+    y.foo();
+    z.foo();
+    x.foo2();
+    y.foo2();
+    z.foo2();
+}"#,
         expect![[r#"
             29..33 'self': &Self
             54..58 'self': &Self
@@ -1329,22 +1348,21 @@ fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
 fn dyn_trait_in_impl() {
     check_infer(
         r#"
-        trait Trait<T, U> {
-            fn foo(&self) -> (T, U);
-        }
-        struct S<T, U> {}
-        impl<T, U> S<T, U> {
-            fn bar(&self) -> &dyn Trait<T, U> { loop {} }
-        }
-        trait Trait2<T, U> {
-            fn baz(&self) -> (T, U);
-        }
-        impl<T, U> Trait2<T, U> for dyn Trait<T, U> { }
+trait Trait<T, U> {
+    fn foo(&self) -> (T, U);
+}
+struct S<T, U> {}
+impl<T, U> S<T, U> {
+    fn bar(&self) -> &dyn Trait<T, U> { loop {} }
+}
+trait Trait2<T, U> {
+    fn baz(&self) -> (T, U);
+}
+impl<T, U> Trait2<T, U> for dyn Trait<T, U> { }
 
-        fn test(s: S<u32, i32>) {
-            s.bar().baz();
-        }
-        "#,
+fn test(s: S<u32, i32>) {
+    s.bar().baz();
+}"#,
         expect![[r#"
             32..36 'self': &Self
             102..106 'self': &S<T, U>
@@ -1365,20 +1383,19 @@ fn test(s: S<u32, i32>) {
 fn dyn_trait_bare() {
     check_infer(
         r#"
-        trait Trait {
-            fn foo(&self) -> u64;
-        }
-        fn bar() -> Trait {}
+trait Trait {
+    fn foo(&self) -> u64;
+}
+fn bar() -> Trait {}
 
-        fn test(x: Trait, y: &Trait) -> u64 {
-            x;
-            y;
-            let z = bar();
-            x.foo();
-            y.foo();
-            z.foo();
-        }
-        "#,
+fn test(x: Trait, y: &Trait) -> u64 {
+    x;
+    y;
+    let z = bar();
+    x.foo();
+    y.foo();
+    z.foo();
+}"#,
         expect![[r#"
             26..30 'self': &Self
             60..62 '{}': ()
@@ -1404,17 +1421,24 @@ fn test(x: Trait, y: &Trait) -> u64 {
 fn weird_bounds() {
     check_infer(
         r#"
-        trait Trait {}
-        fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {}
-        "#,
+trait Trait {}
+fn test(
+    a: impl Trait + 'lifetime,
+    b: impl 'lifetime,
+    c: impl (Trait),
+    d: impl ('lifetime),
+    e: impl ?Sized,
+    f: impl Trait + ?Sized
+) {}
+"#,
         expect![[r#"
-            23..24 'a': impl Trait
-            50..51 'b': impl
-            69..70 'c': impl Trait
-            86..87 'd': impl
-            107..108 'e': impl {error}
-            123..124 'f': impl Trait + {error}
-            147..149 '{}': ()
+            28..29 'a': impl Trait
+            59..60 'b': impl
+            82..83 'c': impl Trait
+            103..104 'd': impl
+            128..129 'e': impl
+            148..149 'f': impl Trait
+            173..175 '{}': ()
         "#]],
     );
 }
@@ -1439,27 +1463,26 @@ fn test(x: (impl Trait + UnknownTrait)) {
 fn assoc_type_bindings() {
     check_infer(
         r#"
-        trait Trait {
-            type Type;
-        }
+trait Trait {
+    type Type;
+}
 
-        fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
-        fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
-        fn set<T: Trait<Type = u64>>(t: T) -> T {t}
-
-        struct S<T>;
-        impl<T> Trait for S<T> { type Type = T; }
-
-        fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
-            get(x);
-            get2(x);
-            get(y);
-            get2(y);
-            get(set(S));
-            get2(set(S));
-            get2(S::<str>);
-        }
-        "#,
+fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
+fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
+fn set<T: Trait<Type = u64>>(t: T) -> T {t}
+
+struct S<T>;
+impl<T> Trait for S<T> { type Type = T; }
+
+fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
+    get(x);
+    get2(x);
+    get(y);
+    get2(y);
+    get(set(S));
+    get2(set(S));
+    get2(S::<str>);
+}"#,
         expect![[r#"
             49..50 't': T
             77..79 '{}': ()
@@ -1546,18 +1569,17 @@ impl<T: Iterator> IntoIterator for T {
 fn projection_eq_within_chalk() {
     check_infer(
         r#"
-        trait Trait1 {
-            type Type;
-        }
-        trait Trait2<T> {
-            fn foo(self) -> T;
-        }
-        impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
+trait Trait1 {
+    type Type;
+}
+trait Trait2<T> {
+    fn foo(self) -> T;
+}
+impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
 
-        fn test<T: Trait1<Type = u32>>(x: T) {
-            x.foo();
-        }
-        "#,
+fn test<T: Trait1<Type = u32>>(x: T) {
+    x.foo();
+}"#,
         expect![[r#"
             61..65 'self': Self
             163..164 'x': T
@@ -1589,19 +1611,18 @@ fn test<T: foo::Trait>(x: T) {
 fn super_trait_method_resolution() {
     check_infer(
         r#"
-        mod foo {
-            trait SuperTrait {
-                fn foo(&self) -> u32 {}
-            }
-        }
-        trait Trait1: foo::SuperTrait {}
-        trait Trait2 where Self: foo::SuperTrait {}
+mod foo {
+    trait SuperTrait {
+        fn foo(&self) -> u32 {}
+    }
+}
+trait Trait1: foo::SuperTrait {}
+trait Trait2 where Self: foo::SuperTrait {}
 
-        fn test<T: Trait1, U: Trait2>(x: T, y: U) {
-            x.foo();
-            y.foo();
-        }
-        "#,
+fn test<T: Trait1, U: Trait2>(x: T, y: U) {
+    x.foo();
+    y.foo();
+}"#,
         expect![[r#"
             49..53 'self': &Self
             62..64 '{}': ()
@@ -1620,17 +1641,16 @@ fn test<T: Trait1, U: Trait2>(x: T, y: U) {
 fn super_trait_impl_trait_method_resolution() {
     check_infer(
         r#"
-        mod foo {
-            trait SuperTrait {
-                fn foo(&self) -> u32 {}
-            }
-        }
-        trait Trait1: foo::SuperTrait {}
+mod foo {
+    trait SuperTrait {
+        fn foo(&self) -> u32 {}
+    }
+}
+trait Trait1: foo::SuperTrait {}
 
-        fn test(x: &impl Trait1) {
-            x.foo();
-        }
-        "#,
+fn test(x: &impl Trait1) {
+    x.foo();
+}"#,
         expect![[r#"
             49..53 'self': &Self
             62..64 '{}': ()
@@ -1667,20 +1687,19 @@ fn test<T: A>(x: T) {
 fn super_trait_assoc_type_bounds() {
     check_infer(
         r#"
-        trait SuperTrait { type Type; }
-        trait Trait where Self: SuperTrait {}
+trait SuperTrait { type Type; }
+trait Trait where Self: SuperTrait {}
 
-        fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
-        fn set<T: Trait<Type = u64>>(t: T) -> T {t}
+fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
+fn set<T: Trait<Type = u64>>(t: T) -> T {t}
 
-        struct S<T>;
-        impl<T> SuperTrait for S<T> { type Type = T; }
-        impl<T> Trait for S<T> {}
+struct S<T>;
+impl<T> SuperTrait for S<T> { type Type = T; }
+impl<T> Trait for S<T> {}
 
-        fn test() {
-            get2(set(S));
-        }
-        "#,
+fn test() {
+    get2(set(S));
+}"#,
         expect![[r#"
             102..103 't': T
             113..115 '{}': ()
@@ -1699,18 +1718,17 @@ fn test() {
 
 #[test]
 fn fn_trait() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
-        trait FnOnce<Args> {
-            type Output;
+trait FnOnce<Args> {
+    type Output;
 
-            fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
-        }
+    fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
+}
 
-        fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
-            f.call_once((1, 2));
-        }
-        "#,
+fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
+    f.call_once((1, 2));
+}"#,
         expect![[r#"
             56..60 'self': Self
             62..66 'args': Args
@@ -1727,57 +1745,60 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
 
 #[test]
 fn fn_ptr_and_item() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
-        #[lang="fn_once"]
-        trait FnOnce<Args> {
-            type Output;
+#[lang="fn_once"]
+trait FnOnce<Args> {
+    type Output;
 
-            fn call_once(self, args: Args) -> Self::Output;
-        }
+    fn call_once(self, args: Args) -> Self::Output;
+}
 
-        trait Foo<T> {
-            fn foo(&self) -> T;
-        }
+trait Foo<T> {
+    fn foo(&self) -> T;
+}
 
-        struct Bar<T>(T);
+struct Bar<T>(T);
 
-        impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
-            fn foo(&self) -> (A1, R) {}
-        }
+impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
+    fn foo(&self) -> (A1, R) { loop {} }
+}
 
-        enum Opt<T> { None, Some(T) }
-        impl<T> Opt<T> {
-            fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {}
-        }
+enum Opt<T> { None, Some(T) }
+impl<T> Opt<T> {
+    fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} }
+}
 
-        fn test() {
-            let bar: Bar<fn(u8) -> u32>;
-            bar.foo();
+fn test() {
+    let bar: Bar<fn(u8) -> u32>;
+    bar.foo();
 
-            let opt: Opt<u8>;
-            let f: fn(u8) -> u32;
-            opt.map(f);
-        }
-        "#,
+    let opt: Opt<u8>;
+    let f: fn(u8) -> u32;
+    opt.map(f);
+}"#,
         expect![[r#"
             74..78 'self': Self
             80..84 'args': Args
             139..143 'self': &Self
             243..247 'self': &Bar<F>
-            260..262 '{}': ()
-            346..350 'self': Opt<T>
-            352..353 'f': F
-            368..370 '{}': ()
-            384..500 '{     ...(f); }': ()
-            394..397 'bar': Bar<fn(u8) -> u32>
-            423..426 'bar': Bar<fn(u8) -> u32>
-            423..432 'bar.foo()': (u8, u32)
-            443..446 'opt': Opt<u8>
-            465..466 'f': fn(u8) -> u32
-            487..490 'opt': Opt<u8>
-            487..497 'opt.map(f)': Opt<u32>
-            495..496 'f': fn(u8) -> u32
+            260..271 '{ loop {} }': (A1, R)
+            262..269 'loop {}': !
+            267..269 '{}': ()
+            355..359 'self': Opt<T>
+            361..362 'f': F
+            377..388 '{ loop {} }': Opt<U>
+            379..386 'loop {}': !
+            384..386 '{}': ()
+            402..518 '{     ...(f); }': ()
+            412..415 'bar': Bar<fn(u8) -> u32>
+            441..444 'bar': Bar<fn(u8) -> u32>
+            441..450 'bar.foo()': (u8, u32)
+            461..464 'opt': Opt<u8>
+            483..484 'f': fn(u8) -> u32
+            505..508 'opt': Opt<u8>
+            505..515 'opt.map(f)': Opt<u32>
+            513..514 'f': fn(u8) -> u32
         "#]],
     );
 }
@@ -1786,46 +1807,45 @@ fn test() {
 fn fn_trait_deref_with_ty_default() {
     check_infer(
         r#"
-        #[lang = "deref"]
-        trait Deref {
-            type Target;
+#[lang = "deref"]
+trait Deref {
+    type Target;
 
-            fn deref(&self) -> &Self::Target;
-        }
+    fn deref(&self) -> &Self::Target;
+}
 
-        #[lang="fn_once"]
-        trait FnOnce<Args> {
-            type Output;
+#[lang="fn_once"]
+trait FnOnce<Args> {
+    type Output;
 
-            fn call_once(self, args: Args) -> Self::Output;
-        }
+    fn call_once(self, args: Args) -> Self::Output;
+}
 
-        struct Foo;
+struct Foo;
 
-        impl Foo {
-            fn foo(&self) -> usize {}
-        }
+impl Foo {
+    fn foo(&self) -> usize {}
+}
 
-        struct Lazy<T, F = fn() -> T>(F);
+struct Lazy<T, F = fn() -> T>(F);
 
-        impl<T, F> Lazy<T, F> {
-            pub fn new(f: F) -> Lazy<T, F> {}
-        }
+impl<T, F> Lazy<T, F> {
+    pub fn new(f: F) -> Lazy<T, F> {}
+}
 
-        impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
-            type Target = T;
-        }
+impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
+    type Target = T;
+}
 
-        fn test() {
-            let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo);
-            let r1 = lazy1.foo();
+fn test() {
+    let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo);
+    let r1 = lazy1.foo();
 
-            fn make_foo_fn() -> Foo {}
-            let make_foo_fn_ptr: fn() -> Foo = make_foo_fn;
-            let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr);
-            let r2 = lazy2.foo();
-        }
-        "#,
+    fn make_foo_fn() -> Foo {}
+    let make_foo_fn_ptr: fn() -> Foo = make_foo_fn;
+    let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr);
+    let r2 = lazy2.foo();
+}"#,
         expect![[r#"
             64..68 'self': &Self
             165..169 'self': Self
@@ -1859,172 +1879,205 @@ fn make_foo_fn() -> Foo {}
 
 #[test]
 fn closure_1() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
-        #[lang = "fn_once"]
-        trait FnOnce<Args> {
-            type Output;
-        }
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+    type Output;
+}
 
-        enum Option<T> { Some(T), None }
-        impl<T> Option<T> {
-            fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {}
-        }
+enum Option<T> { Some(T), None }
+impl<T> Option<T> {
+    fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
+}
 
-        fn test() {
-            let x = Option::Some(1u32);
-            x.map(|v| v + 1);
-            x.map(|_v| 1u64);
-            let y: Option<i64> = x.map(|_v| 1);
-        }
-        "#,
+fn test() {
+    let x = Option::Some(1u32);
+    x.map(|v| v + 1);
+    x.map(|_v| 1u64);
+    let y: Option<i64> = x.map(|_v| 1);
+}"#,
         expect![[r#"
             147..151 'self': Option<T>
             153..154 'f': F
-            172..174 '{}': ()
-            188..307 '{     ... 1); }': ()
-            198..199 'x': Option<u32>
-            202..214 'Option::Some': Some<u32>(u32) -> Option<u32>
-            202..220 'Option...(1u32)': Option<u32>
-            215..219 '1u32': u32
-            226..227 'x': Option<u32>
-            226..242 'x.map(...v + 1)': Option<u32>
-            232..241 '|v| v + 1': |u32| -> u32
-            233..234 'v': u32
-            236..237 'v': u32
-            236..241 'v + 1': u32
-            240..241 '1': u32
-            248..249 'x': Option<u32>
-            248..264 'x.map(... 1u64)': Option<u64>
-            254..263 '|_v| 1u64': |u32| -> u64
-            255..257 '_v': u32
-            259..263 '1u64': u64
-            274..275 'y': Option<i64>
-            291..292 'x': Option<u32>
-            291..304 'x.map(|_v| 1)': Option<i64>
-            297..303 '|_v| 1': |u32| -> i64
-            298..300 '_v': u32
-            302..303 '1': i64
+            172..183 '{ loop {} }': Option<U>
+            174..181 'loop {}': !
+            179..181 '{}': ()
+            197..316 '{     ... 1); }': ()
+            207..208 'x': Option<u32>
+            211..223 'Option::Some': Some<u32>(u32) -> Option<u32>
+            211..229 'Option...(1u32)': Option<u32>
+            224..228 '1u32': u32
+            235..236 'x': Option<u32>
+            235..251 'x.map(...v + 1)': Option<u32>
+            241..250 '|v| v + 1': |u32| -> u32
+            242..243 'v': u32
+            245..246 'v': u32
+            245..250 'v + 1': u32
+            249..250 '1': u32
+            257..258 'x': Option<u32>
+            257..273 'x.map(... 1u64)': Option<u64>
+            263..272 '|_v| 1u64': |u32| -> u64
+            264..266 '_v': u32
+            268..272 '1u64': u64
+            283..284 'y': Option<i64>
+            300..301 'x': Option<u32>
+            300..313 'x.map(|_v| 1)': Option<i64>
+            306..312 '|_v| 1': |u32| -> i64
+            307..309 '_v': u32
+            311..312 '1': i64
         "#]],
     );
 }
 
 #[test]
 fn closure_2() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
-        trait FnOnce<Args> {
-            type Output;
-        }
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+    type Output;
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
 
-        fn test<F: FnOnce(u32) -> u64>(f: F) {
-            f(1);
-            let g = |v| v + 1;
-            g(1u64);
-            let h = |v| 1u128 + v;
-        }
-        "#,
+trait FnOnce<Args> {
+    type Output;
+}
+
+impl Add for u64 {
+    type Output = Self;
+    fn add(self, rhs: u64) -> Self::Output {0}
+}
+
+impl Add for u128 {
+    type Output = Self;
+    fn add(self, rhs: u128) -> Self::Output {0}
+}
+
+fn test<F: FnOnce(u32) -> u64>(f: F) {
+    f(1);
+    let g = |v| v + 1;
+    g(1u64);
+    let h = |v| 1u128 + v;
+}"#,
         expect![[r#"
-            72..73 'f': F
-            78..154 '{     ...+ v; }': ()
-            84..85 'f': F
-            84..88 'f(1)': {unknown}
-            86..87 '1': i32
-            98..99 'g': |u64| -> i32
-            102..111 '|v| v + 1': |u64| -> i32
-            103..104 'v': u64
-            106..107 'v': u64
-            106..111 'v + 1': i32
-            110..111 '1': i32
-            117..118 'g': |u64| -> i32
-            117..124 'g(1u64)': i32
-            119..123 '1u64': u64
-            134..135 'h': |u128| -> u128
-            138..151 '|v| 1u128 + v': |u128| -> u128
-            139..140 'v': u128
-            142..147 '1u128': u128
-            142..151 '1u128 + v': u128
-            150..151 'v': u128
+            72..76 'self': Self
+            78..81 'rhs': Rhs
+            203..207 'self': u64
+            209..212 'rhs': u64
+            235..238 '{0}': u64
+            236..237 '0': u64
+            297..301 'self': u128
+            303..306 'rhs': u128
+            330..333 '{0}': u128
+            331..332 '0': u128
+            368..369 'f': F
+            374..450 '{     ...+ v; }': ()
+            380..381 'f': F
+            380..384 'f(1)': {unknown}
+            382..383 '1': i32
+            394..395 'g': |u64| -> u64
+            398..407 '|v| v + 1': |u64| -> u64
+            399..400 'v': u64
+            402..403 'v': u64
+            402..407 'v + 1': u64
+            406..407 '1': u64
+            413..414 'g': |u64| -> u64
+            413..420 'g(1u64)': u64
+            415..419 '1u64': u64
+            430..431 'h': |u128| -> u128
+            434..447 '|v| 1u128 + v': |u128| -> u128
+            435..436 'v': u128
+            438..443 '1u128': u128
+            438..447 '1u128 + v': u128
+            446..447 'v': u128
         "#]],
     );
 }
 
 #[test]
 fn closure_as_argument_inference_order() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
-        #[lang = "fn_once"]
-        trait FnOnce<Args> {
-            type Output;
-        }
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+    type Output;
+}
 
-        fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {}
-        fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {}
+fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
+fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
 
-        struct S;
-        impl S {
-            fn method(self) -> u64;
+struct S;
+impl S {
+    fn method(self) -> u64;
 
-            fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {}
-            fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {}
-        }
+    fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} }
+    fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} }
+}
 
-        fn test() {
-            let x1 = foo1(S, |s| s.method());
-            let x2 = foo2(|s| s.method(), S);
-            let x3 = S.foo1(S, |s| s.method());
-            let x4 = S.foo2(|s| s.method(), S);
-        }
-        "#,
+fn test() {
+    let x1 = foo1(S, |s| s.method());
+    let x2 = foo2(|s| s.method(), S);
+    let x3 = S.foo1(S, |s| s.method());
+    let x4 = S.foo2(|s| s.method(), S);
+}"#,
         expect![[r#"
             94..95 'x': T
             100..101 'f': F
-            111..113 '{}': ()
-            147..148 'f': F
-            153..154 'x': T
-            164..166 '{}': ()
-            201..205 'self': S
-            253..257 'self': S
-            259..260 'x': T
-            265..266 'f': F
-            276..278 '{}': ()
-            316..320 'self': S
-            322..323 'f': F
-            328..329 'x': T
-            339..341 '{}': ()
-            355..514 '{     ... S); }': ()
-            365..367 'x1': u64
-            370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
-            370..393 'foo1(S...hod())': u64
-            375..376 'S': S
-            378..392 '|s| s.method()': |S| -> u64
-            379..380 's': S
-            382..383 's': S
-            382..392 's.method()': u64
-            403..405 'x2': u64
-            408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
-            408..431 'foo2(|...(), S)': u64
-            413..427 '|s| s.method()': |S| -> u64
-            414..415 's': S
-            417..418 's': S
-            417..427 's.method()': u64
-            429..430 'S': S
-            441..443 'x3': u64
-            446..447 'S': S
-            446..471 'S.foo1...hod())': u64
-            453..454 'S': S
-            456..470 '|s| s.method()': |S| -> u64
-            457..458 's': S
-            460..461 's': S
-            460..470 's.method()': u64
-            481..483 'x4': u64
-            486..487 'S': S
-            486..511 'S.foo2...(), S)': u64
-            493..507 '|s| s.method()': |S| -> u64
-            494..495 's': S
-            497..498 's': S
-            497..507 's.method()': u64
-            509..510 'S': S
+            111..122 '{ loop {} }': U
+            113..120 'loop {}': !
+            118..120 '{}': ()
+            156..157 'f': F
+            162..163 'x': T
+            173..184 '{ loop {} }': U
+            175..182 'loop {}': !
+            180..182 '{}': ()
+            219..223 'self': S
+            271..275 'self': S
+            277..278 'x': T
+            283..284 'f': F
+            294..305 '{ loop {} }': U
+            296..303 'loop {}': !
+            301..303 '{}': ()
+            343..347 'self': S
+            349..350 'f': F
+            355..356 'x': T
+            366..377 '{ loop {} }': U
+            368..375 'loop {}': !
+            373..375 '{}': ()
+            391..550 '{     ... S); }': ()
+            401..403 'x1': u64
+            406..410 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
+            406..429 'foo1(S...hod())': u64
+            411..412 'S': S
+            414..428 '|s| s.method()': |S| -> u64
+            415..416 's': S
+            418..419 's': S
+            418..428 's.method()': u64
+            439..441 'x2': u64
+            444..448 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
+            444..467 'foo2(|...(), S)': u64
+            449..463 '|s| s.method()': |S| -> u64
+            450..451 's': S
+            453..454 's': S
+            453..463 's.method()': u64
+            465..466 'S': S
+            477..479 'x3': u64
+            482..483 'S': S
+            482..507 'S.foo1...hod())': u64
+            489..490 'S': S
+            492..506 '|s| s.method()': |S| -> u64
+            493..494 's': S
+            496..497 's': S
+            496..506 's.method()': u64
+            517..519 'x4': u64
+            522..523 'S': S
+            522..547 'S.foo2...(), S)': u64
+            529..543 '|s| s.method()': |S| -> u64
+            530..531 's': S
+            533..534 's': S
+            533..543 's.method()': u64
+            545..546 'S': S
         "#]],
     );
 }
@@ -2096,27 +2149,26 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
 fn unselected_projection_on_impl_self() {
     check_infer(
         r#"
-        //- /main.rs
-        trait Trait {
-            type Item;
+//- /main.rs
+trait Trait {
+    type Item;
 
-            fn f(&self, x: Self::Item);
-        }
+    fn f(&self, x: Self::Item);
+}
 
-        struct S;
+struct S;
 
-        impl Trait for S {
-            type Item = u32;
-            fn f(&self, x: Self::Item) { let y = x; }
-        }
+impl Trait for S {
+    type Item = u32;
+    fn f(&self, x: Self::Item) { let y = x; }
+}
 
-        struct S2;
+struct S2;
 
-        impl Trait for S2 {
-            type Item = i32;
-            fn f(&self, x: <Self>::Item) { let y = x; }
-        }
-        "#,
+impl Trait for S2 {
+    type Item = i32;
+    fn f(&self, x: <Self>::Item) { let y = x; }
+}"#,
         expect![[r#"
             40..44 'self': &Self
             46..47 'x': Trait::Item<Self>
@@ -2257,6 +2309,56 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
     );
 }
 
+#[test]
+fn unselected_projection_in_trait_env_cycle_3() {
+    // this is a cycle for rustc; we currently accept it
+    check_types(
+        r#"
+//- /main.rs
+trait Trait {
+    type Item;
+    type OtherItem;
+}
+
+fn test<T>() where T: Trait<OtherItem = T::Item> {
+    let x: T::Item = no_matter;
+}                   //^ Trait::Item<T>
+"#,
+    );
+}
+
+#[test]
+fn unselected_projection_in_trait_env_no_cycle() {
+    // this is not a cycle
+    check_types(
+        r#"
+//- /main.rs
+trait Index {
+    type Output;
+}
+
+type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
+
+pub trait UnificationStoreBase: Index<Output = Key<Self>> {
+    type Key;
+
+    fn len(&self) -> usize;
+}
+
+pub trait UnificationStoreMut: UnificationStoreBase {
+    fn push(&mut self, value: Self::Key);
+}
+
+fn test<T>(t: T) where T: UnificationStoreMut {
+    let x;
+    t.push(x);
+    let y: Key<T>;
+    (x, y);
+}      //^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
+"#,
+    );
+}
+
 #[test]
 fn inline_assoc_type_bounds_1() {
     check_types(
@@ -2302,58 +2404,57 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
 fn proc_macro_server_types() {
     check_infer(
         r#"
-        macro_rules! with_api {
-            ($S:ident, $self:ident, $m:ident) => {
-                $m! {
-                    TokenStream {
-                        fn new() -> $S::TokenStream;
-                    },
-                    Group {
-                    },
-                }
-            };
+macro_rules! with_api {
+    ($S:ident, $self:ident, $m:ident) => {
+        $m! {
+            TokenStream {
+                fn new() -> $S::TokenStream;
+            },
+            Group {
+            },
         }
-        macro_rules! associated_item {
-            (type TokenStream) =>
-                (type TokenStream: 'static;);
-            (type Group) =>
-                (type Group: 'static;);
-            ($($item:tt)*) => ($($item)*;)
-        }
-        macro_rules! declare_server_traits {
-            ($($name:ident {
-                $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-            }),* $(,)?) => {
-                pub trait Types {
-                    $(associated_item!(type $name);)*
-                }
-
-                $(pub trait $name: Types {
-                    $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
-                })*
-
-                pub trait Server: Types $(+ $name)* {}
-                impl<S: Types $(+ $name)*> Server for S {}
-            }
+    };
+}
+macro_rules! associated_item {
+    (type TokenStream) =>
+        (type TokenStream: 'static;);
+    (type Group) =>
+        (type Group: 'static;);
+    ($($item:tt)*) => ($($item)*;)
+}
+macro_rules! declare_server_traits {
+    ($($name:ident {
+        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
+    }),* $(,)?) => {
+        pub trait Types {
+            $(associated_item!(type $name);)*
         }
 
-        with_api!(Self, self_, declare_server_traits);
-        struct G {}
-        struct T {}
-        struct Rustc;
-        impl Types for Rustc {
-            type TokenStream = T;
-            type Group = G;
-        }
+        $(pub trait $name: Types {
+            $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
+        })*
 
-        fn make<T>() -> T { loop {} }
-        impl TokenStream for Rustc {
-            fn new() -> Self::TokenStream {
-                let group: Self::Group = make();
-                make()
-            }
-        }
-        "#,
+        pub trait Server: Types $(+ $name)* {}
+        impl<S: Types $(+ $name)*> Server for S {}
+    }
+}
+
+with_api!(Self, self_, declare_server_traits);
+struct G {}
+struct T {}
+struct Rustc;
+impl Types for Rustc {
+    type TokenStream = T;
+    type Group = G;
+}
+
+fn make<T>() -> T { loop {} }
+impl TokenStream for Rustc {
+    fn new() -> Self::TokenStream {
+        let group: Self::Group = make();
+        make()
+    }
+}"#,
         expect![[r#"
             1061..1072 '{ loop {} }': T
             1063..1070 'loop {}': !
@@ -2372,23 +2473,22 @@ fn new() -> Self::TokenStream {
 fn unify_impl_trait() {
     check_infer_with_mismatches(
         r#"
-        trait Trait<T> {}
+trait Trait<T> {}
 
-        fn foo(x: impl Trait<u32>) { loop {} }
-        fn bar<T>(x: impl Trait<T>) -> T { loop {} }
+fn foo(x: impl Trait<u32>) { loop {} }
+fn bar<T>(x: impl Trait<T>) -> T { loop {} }
 
-        struct S<T>(T);
-        impl<T> Trait<T> for S<T> {}
+struct S<T>(T);
+impl<T> Trait<T> for S<T> {}
 
-        fn default<T>() -> T { loop {} }
+fn default<T>() -> T { loop {} }
 
-        fn test() -> impl Trait<i32> {
-            let s1 = S(default());
-            foo(s1);
-            let x: i32 = bar(S(default()));
-            S(default())
-        }
-        "#,
+fn test() -> impl Trait<i32> {
+    let s1 = S(default());
+    foo(s1);
+    let x: i32 = bar(S(default()));
+    S(default())
+}"#,
         expect![[r#"
             26..27 'x': impl Trait<u32>
             46..57 '{ loop {} }': ()
@@ -2429,30 +2529,29 @@ fn test() -> impl Trait<i32> {
 fn assoc_types_from_bounds() {
     check_infer(
         r#"
-        //- /main.rs
-        #[lang = "fn_once"]
-        trait FnOnce<Args> {
-            type Output;
-        }
+//- /main.rs
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+    type Output;
+}
 
-        trait T {
-            type O;
-        }
+trait T {
+    type O;
+}
 
-        impl T for () {
-            type O = ();
-        }
+impl T for () {
+    type O = ();
+}
 
-        fn f<X, F>(_v: F)
-        where
-            X: T,
-            F: FnOnce(&X::O),
-        { }
+fn f<X, F>(_v: F)
+where
+    X: T,
+    F: FnOnce(&X::O),
+{ }
 
-        fn main() {
-            f::<(), _>(|z| { z; });
-        }
-        "#,
+fn main() {
+    f::<(), _>(|z| { z; });
+}"#,
         expect![[r#"
             133..135 '_v': F
             178..181 '{ }': ()
@@ -2536,78 +2635,77 @@ fn test() {
 
 #[test]
 fn iterator_chain() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
-        //- /main.rs
-        #[lang = "fn_once"]
-        trait FnOnce<Args> {
-            type Output;
-        }
-        #[lang = "fn_mut"]
-        trait FnMut<Args>: FnOnce<Args> { }
+//- /main.rs
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+    type Output;
+}
+#[lang = "fn_mut"]
+trait FnMut<Args>: FnOnce<Args> { }
 
-        enum Option<T> { Some(T), None }
-        use Option::*;
+enum Option<T> { Some(T), None }
+use Option::*;
 
-        pub trait Iterator {
-            type Item;
+pub trait Iterator {
+    type Item;
 
-            fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
-            where
-                F: FnMut(Self::Item) -> Option<B>,
-            { loop {} }
+    fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
+    where
+        F: FnMut(Self::Item) -> Option<B>,
+    { loop {} }
 
-            fn for_each<F>(self, f: F)
-            where
-                F: FnMut(Self::Item),
-            { loop {} }
-        }
+    fn for_each<F>(self, f: F)
+    where
+        F: FnMut(Self::Item),
+    { loop {} }
+}
 
-        pub trait IntoIterator {
-            type Item;
-            type IntoIter: Iterator<Item = Self::Item>;
-            fn into_iter(self) -> Self::IntoIter;
-        }
+pub trait IntoIterator {
+    type Item;
+    type IntoIter: Iterator<Item = Self::Item>;
+    fn into_iter(self) -> Self::IntoIter;
+}
 
-        pub struct FilterMap<I, F> { }
-        impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
-        where
-            F: FnMut(I::Item) -> Option<B>,
-        {
-            type Item = B;
-        }
+pub struct FilterMap<I, F> { }
+impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
+where
+    F: FnMut(I::Item) -> Option<B>,
+{
+    type Item = B;
+}
 
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<I: Iterator> IntoIterator for I {
-            type Item = I::Item;
-            type IntoIter = I;
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator> IntoIterator for I {
+    type Item = I::Item;
+    type IntoIter = I;
 
-            fn into_iter(self) -> I {
-                self
-            }
-        }
+    fn into_iter(self) -> I {
+        self
+    }
+}
 
-        struct Vec<T> {}
-        impl<T> Vec<T> {
-            fn new() -> Self { loop {} }
-        }
+struct Vec<T> {}
+impl<T> Vec<T> {
+    fn new() -> Self { loop {} }
+}
 
-        impl<T> IntoIterator for Vec<T> {
-            type Item = T;
-            type IntoIter = IntoIter<T>;
-        }
+impl<T> IntoIterator for Vec<T> {
+    type Item = T;
+    type IntoIter = IntoIter<T>;
+}
 
-        pub struct IntoIter<T> { }
-        impl<T> Iterator for IntoIter<T> {
-            type Item = T;
-        }
+pub struct IntoIter<T> { }
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+}
 
-        fn main() {
-            Vec::<i32>::new().into_iter()
-            .filter_map(|x| if x > 0 { Some(x as u32) } else { None })
-            .for_each(|y| { y; });
-        }
-        "#,
+fn main() {
+    Vec::<i32>::new().into_iter()
+    .filter_map(|x| if x > 0 { Some(x as u32) } else { None })
+    .for_each(|y| { y; });
+}"#,
         expect![[r#"
             226..230 'self': Self
             232..233 'f': F
@@ -2689,14 +2787,13 @@ fn main() {
 fn trait_object_no_coercion() {
     check_infer_with_mismatches(
         r#"
-        trait Foo {}
+trait Foo {}
 
-        fn foo(x: &dyn Foo) {}
+fn foo(x: &dyn Foo) {}
 
-        fn test(x: &dyn Foo) {
-            foo(x);
-        }
-        "#,
+fn test(x: &dyn Foo) {
+    foo(x);
+}"#,
         expect![[r#"
             21..22 'x': &dyn Foo
             34..36 '{}': ()
@@ -2713,23 +2810,22 @@ fn test(x: &dyn Foo) {
 fn builtin_copy() {
     check_infer_with_mismatches(
         r#"
-        #[lang = "copy"]
-        trait Copy {}
+#[lang = "copy"]
+trait Copy {}
 
-        struct IsCopy;
-        impl Copy for IsCopy {}
-        struct NotCopy;
+struct IsCopy;
+impl Copy for IsCopy {}
+struct NotCopy;
 
-        trait Test { fn test(&self) -> bool; }
-        impl<T: Copy> Test for T {}
+trait Test { fn test(&self) -> bool; }
+impl<T: Copy> Test for T {}
 
-        fn test() {
-            IsCopy.test();
-            NotCopy.test();
-            (IsCopy, IsCopy).test();
-            (IsCopy, NotCopy).test();
-        }
-        "#,
+fn test() {
+    IsCopy.test();
+    NotCopy.test();
+    (IsCopy, IsCopy).test();
+    (IsCopy, NotCopy).test();
+}"#,
         expect![[r#"
             110..114 'self': &Self
             166..267 '{     ...t(); }': ()
@@ -2753,24 +2849,23 @@ fn test() {
 fn builtin_fn_def_copy() {
     check_infer_with_mismatches(
         r#"
-        #[lang = "copy"]
-        trait Copy {}
+#[lang = "copy"]
+trait Copy {}
 
-        fn foo() {}
-        fn bar<T: Copy>(T) -> T {}
-        struct Struct(usize);
-        enum Enum { Variant(usize) }
+fn foo() {}
+fn bar<T: Copy>(T) -> T {}
+struct Struct(usize);
+enum Enum { Variant(usize) }
 
-        trait Test { fn test(&self) -> bool; }
-        impl<T: Copy> Test for T {}
+trait Test { fn test(&self) -> bool; }
+impl<T: Copy> Test for T {}
 
-        fn test() {
-            foo.test();
-            bar.test();
-            Struct.test();
-            Enum::Variant.test();
-        }
-        "#,
+fn test() {
+    foo.test();
+    bar.test();
+    Struct.test();
+    Enum::Variant.test();
+}"#,
         expect![[r#"
             41..43 '{}': ()
             60..61 'T': {unknown}
@@ -2794,18 +2889,17 @@ fn test() {
 fn builtin_fn_ptr_copy() {
     check_infer_with_mismatches(
         r#"
-        #[lang = "copy"]
-        trait Copy {}
+#[lang = "copy"]
+trait Copy {}
 
-        trait Test { fn test(&self) -> bool; }
-        impl<T: Copy> Test for T {}
+trait Test { fn test(&self) -> bool; }
+impl<T: Copy> Test for T {}
 
-        fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
-            f1.test();
-            f2.test();
-            f3.test();
-        }
-        "#,
+fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
+    f1.test();
+    f2.test();
+    f3.test();
+}"#,
         expect![[r#"
             54..58 'self': &Self
             108..110 'f1': fn()
@@ -2826,19 +2920,18 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
 fn builtin_sized() {
     check_infer_with_mismatches(
         r#"
-        #[lang = "sized"]
-        trait Sized {}
+#[lang = "sized"]
+trait Sized {}
 
-        trait Test { fn test(&self) -> bool; }
-        impl<T: Sized> Test for T {}
+trait Test { fn test(&self) -> bool; }
+impl<T: Sized> Test for T {}
 
-        fn test() {
-            1u8.test();
-            (*"foo").test(); // not Sized
-            (1u8, 1u8).test();
-            (1u8, *"foo").test(); // not Sized
-        }
-        "#,
+fn test() {
+    1u8.test();
+    (*"foo").test(); // not Sized
+    (1u8, 1u8).test();
+    (1u8, *"foo").test(); // not Sized
+}"#,
         expect![[r#"
             56..60 'self': &Self
             113..228 '{     ...ized }': ()
@@ -2908,19 +3001,18 @@ impl<A: Step> iter::Iterator for ops::Range<A> {
 fn infer_closure_arg() {
     check_infer(
         r#"
-        //- /lib.rs
+//- /lib.rs
 
-        enum Option<T> {
-            None,
-            Some(T)
-        }
+enum Option<T> {
+    None,
+    Some(T)
+}
 
-        fn foo() {
-            let s = Option::None;
-            let f = |x: Option<i32>| {};
-            (&f)(s)
-        }
-        "#,
+fn foo() {
+    let s = Option::None;
+    let f = |x: Option<i32>| {};
+    (&f)(s)
+}"#,
         expect![[r#"
             52..126 '{     ...)(s) }': ()
             62..63 's': Option<i32>
@@ -2939,7 +3031,7 @@ fn foo() {
 
 #[test]
 fn infer_fn_trait_arg() {
-    check_infer(
+    check_infer_with_mismatches(
         r#"
         //- /lib.rs deps:std
 
@@ -2986,48 +3078,48 @@ fn foo<F, T>(f: F) -> T
 
 #[test]
 fn infer_box_fn_arg() {
-    check_infer(
+    // The type mismatch is because we don't define Unsize and CoerceUnsized
+    check_infer_with_mismatches(
         r#"
-        //- /lib.rs deps:std
+//- /lib.rs deps:std
 
-        #[lang = "fn_once"]
-        pub trait FnOnce<Args> {
-            type Output;
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    type Output;
 
-            extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-        }
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
 
-        #[lang = "deref"]
-        pub trait Deref {
-            type Target: ?Sized;
+#[lang = "deref"]
+pub trait Deref {
+    type Target: ?Sized;
 
-            fn deref(&self) -> &Self::Target;
-        }
+    fn deref(&self) -> &Self::Target;
+}
 
-        #[lang = "owned_box"]
-        pub struct Box<T: ?Sized> {
-            inner: *mut T,
-        }
+#[lang = "owned_box"]
+pub struct Box<T: ?Sized> {
+    inner: *mut T,
+}
 
-        impl<T: ?Sized> Deref for Box<T> {
-            type Target = T;
+impl<T: ?Sized> Deref for Box<T> {
+    type Target = T;
 
-            fn deref(&self) -> &T {
-                &self.inner
-            }
-        }
+    fn deref(&self) -> &T {
+        &self.inner
+    }
+}
 
-        enum Option<T> {
-            None,
-            Some(T)
-        }
+enum Option<T> {
+    None,
+    Some(T)
+}
 
-        fn foo() {
-            let s = Option::None;
-            let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
-            f(&s)
-        }
-        "#,
+fn foo() {
+    let s = Option::None;
+    let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
+    f(&s);
+}"#,
         expect![[r#"
             100..104 'self': Self
             106..110 'args': Args
@@ -3037,7 +3129,7 @@ fn foo() {
             406..417 '&self.inner': &*mut T
             407..411 'self': &Box<T>
             407..417 'self.inner': *mut T
-            478..575 '{     ...(&s) }': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
+            478..576 '{     ...&s); }': ()
             488..489 's': Option<i32>
             492..504 'Option::None': Option<i32>
             514..515 'f': Box<dyn FnOnce(&Option<i32>)>
@@ -3046,9 +3138,10 @@ fn foo() {
             555..557 'ps': {unknown}
             559..561 '{}': ()
             568..569 'f': Box<dyn FnOnce(&Option<i32>)>
-            568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
+            568..573 'f(&s)': ()
             570..572 '&s': &Option<i32>
             571..572 's': Option<i32>
+            549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
         "#]],
     );
 }
@@ -3192,8 +3285,7 @@ fn inner() {
         ().method();
       //^^^^^^^^^^^ u8
     }
-}
-        "#,
+}"#,
         expect![[r#"
             46..50 'self': &Self
             58..63 '{ 0 }': u8
@@ -3237,3 +3329,334 @@ fn f() {
         "#,
     );
 }
+
+#[test]
+fn nested_inner_function_calling_self() {
+    check_infer(
+        r#"
+struct S;
+fn f() {
+    fn inner() -> S {
+        let s = inner();
+    }
+}"#,
+        expect![[r#"
+            17..73 '{     ...   } }': ()
+            39..71 '{     ...     }': ()
+            53..54 's': S
+            57..62 'inner': fn inner() -> S
+            57..64 'inner()': S
+        "#]],
+    )
+}
+
+#[test]
+fn infer_default_trait_type_parameter() {
+    check_infer(
+        r#"
+struct A;
+
+trait Op<RHS=Self> {
+    type Output;
+
+    fn do_op(self, rhs: RHS) -> Self::Output;
+}
+
+impl Op for A {
+    type Output = bool;
+
+    fn do_op(self, rhs: Self) -> Self::Output {
+        true
+    }
+}
+
+fn test() {
+    let x = A;
+    let y = A;
+    let r = x.do_op(y);
+}"#,
+        expect![[r#"
+            63..67 'self': Self
+            69..72 'rhs': RHS
+            153..157 'self': A
+            159..162 'rhs': A
+            186..206 '{     ...     }': bool
+            196..200 'true': bool
+            220..277 '{     ...(y); }': ()
+            230..231 'x': A
+            234..235 'A': A
+            245..246 'y': A
+            249..250 'A': A
+            260..261 'r': bool
+            264..265 'x': A
+            264..274 'x.do_op(y)': bool
+            272..273 'y': A
+        "#]],
+    )
+}
+
+#[test]
+fn qualified_path_as_qualified_trait() {
+    check_infer(
+        r#"
+mod foo {
+
+    pub trait Foo {
+        type Target;
+    }
+    pub trait Bar {
+        type Output;
+        fn boo() -> Self::Output {
+            loop {}
+        }
+    }
+}
+
+struct F;
+impl foo::Foo for F {
+    type Target = ();
+}
+impl foo::Bar for F {
+    type Output = <F as foo::Foo>::Target;
+}
+
+fn foo() {
+    use foo::Bar;
+    let x = <F as Bar>::boo();
+}"#,
+        expect![[r#"
+            132..163 '{     ...     }': Bar::Output<Self>
+            146..153 'loop {}': !
+            151..153 '{}': ()
+            306..358 '{     ...o(); }': ()
+            334..335 'x': ()
+            338..353 '<F as Bar>::boo': fn boo<F>() -> <F as Bar>::Output
+            338..355 '<F as ...:boo()': ()
+        "#]],
+    );
+}
+
+#[test]
+fn renamed_extern_crate_in_block() {
+    check_types(
+        r#"
+//- /lib.rs crate:lib deps:serde
+use serde::Deserialize;
+
+struct Foo {}
+
+const _ : () = {
+    extern crate serde as _serde;
+    impl _serde::Deserialize for Foo {
+        fn deserialize() -> u8 { 0 }
+    }
+};
+
+fn foo() {
+    Foo::deserialize();
+  //^^^^^^^^^^^^^^^^^^ u8
+}
+
+//- /serde.rs crate:serde
+
+pub trait Deserialize {
+    fn deserialize() -> u8;
+}"#,
+    );
+}
+
+#[test]
+fn bin_op_adt_with_rhs_primitive() {
+    check_infer_with_mismatches(
+        r#"
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+    type Output;
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+struct Wrapper(u32);
+impl Add<u32> for Wrapper {
+    type Output = Self;
+    fn add(self, rhs: u32) -> Wrapper {
+        Wrapper(rhs)
+    }
+}
+fn main(){
+    let wrapped = Wrapper(10);
+    let num: u32 = 2;
+    let res = wrapped + num;
+
+}"#,
+        expect![[r#"
+            72..76 'self': Self
+            78..81 'rhs': Rhs
+            192..196 'self': Wrapper
+            198..201 'rhs': u32
+            219..247 '{     ...     }': Wrapper
+            229..236 'Wrapper': Wrapper(u32) -> Wrapper
+            229..241 'Wrapper(rhs)': Wrapper
+            237..240 'rhs': u32
+            259..345 '{     ...um;  }': ()
+            269..276 'wrapped': Wrapper
+            279..286 'Wrapper': Wrapper(u32) -> Wrapper
+            279..290 'Wrapper(10)': Wrapper
+            287..289 '10': u32
+            300..303 'num': u32
+            311..312 '2': u32
+            322..325 'res': Wrapper
+            328..335 'wrapped': Wrapper
+            328..341 'wrapped + num': Wrapper
+            338..341 'num': u32
+        "#]],
+    )
+}
+
+#[test]
+fn array_length() {
+    check_infer(
+        r#"
+trait T {
+    type Output;
+    fn do_thing(&self) -> Self::Output;
+}
+
+impl T for [u8; 4] {
+    type Output = usize;
+    fn do_thing(&self) -> Self::Output {
+        2
+    }
+}
+
+impl T for [u8; 2] {
+    type Output = u8;
+    fn do_thing(&self) -> Self::Output {
+        2
+    }
+}
+
+fn main() {
+    let v = [0u8; 2];
+    let v2 = v.do_thing();
+    let v3 = [0u8; 4];
+    let v4 = v3.do_thing();
+}
+"#,
+        expect![[r#"
+            44..48 'self': &Self
+            133..137 'self': &[u8; 4]
+            155..172 '{     ...     }': usize
+            165..166 '2': usize
+            236..240 'self': &[u8; 2]
+            258..275 '{     ...     }': u8
+            268..269 '2': u8
+            289..392 '{     ...g(); }': ()
+            299..300 'v': [u8; 2]
+            303..311 '[0u8; 2]': [u8; 2]
+            304..307 '0u8': u8
+            309..310 '2': usize
+            321..323 'v2': u8
+            326..327 'v': [u8; 2]
+            326..338 'v.do_thing()': u8
+            348..350 'v3': [u8; 4]
+            353..361 '[0u8; 4]': [u8; 4]
+            354..357 '0u8': u8
+            359..360 '4': usize
+            371..373 'v4': usize
+            376..378 'v3': [u8; 4]
+            376..389 'v3.do_thing()': usize
+        "#]],
+    )
+}
+
+// FIXME: We should infer the length of the returned array :)
+#[test]
+fn const_generics() {
+    check_infer(
+        r#"
+trait T {
+    type Output;
+    fn do_thing(&self) -> Self::Output;
+}
+
+impl<const L: usize> T for [u8; L] {
+    type Output = [u8; L];
+    fn do_thing(&self) -> Self::Output {
+        *self
+    }
+}
+
+fn main() {
+    let v = [0u8; 2];
+    let v2 = v.do_thing();
+}
+"#,
+        expect![[r#"
+            44..48 'self': &Self
+            151..155 'self': &[u8; _]
+            173..194 '{     ...     }': [u8; _]
+            183..188 '*self': [u8; _]
+            184..188 'self': &[u8; _]
+            208..260 '{     ...g(); }': ()
+            218..219 'v': [u8; 2]
+            222..230 '[0u8; 2]': [u8; 2]
+            223..226 '0u8': u8
+            228..229 '2': usize
+            240..242 'v2': [u8; _]
+            245..246 'v': [u8; 2]
+            245..257 'v.do_thing()': [u8; _]
+        "#]],
+    )
+}
+
+#[test]
+fn fn_returning_unit() {
+    check_infer_with_mismatches(
+        r#"
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+    type Output;
+}
+
+fn test<F: FnOnce()>(f: F) {
+    let _: () = f();
+}"#,
+        expect![[r#"
+            82..83 'f': F
+            88..112 '{     ...f(); }': ()
+            98..99 '_': ()
+            106..107 'f': F
+            106..109 'f()': ()
+        "#]],
+    );
+}
+
+#[test]
+fn trait_in_scope_of_trait_impl() {
+    check_infer(
+        r#"
+mod foo {
+    pub trait Foo {
+        fn foo(self);
+        fn bar(self) -> usize { 0 }
+    }
+}
+impl foo::Foo for u32 {
+    fn foo(self) {
+        let _x = self.bar();
+    }
+}
+    "#,
+        expect![[r#"
+            45..49 'self': Self
+            67..71 'self': Self
+            82..87 '{ 0 }': usize
+            84..85 '0': usize
+            131..135 'self': u32
+            137..173 '{     ...     }': ()
+            151..153 '_x': usize
+            156..160 'self': u32
+            156..166 'self.bar()': usize
+        "#]],
+    );
+}