]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests/traits.rs
internal: switch some tests to minicore
[rust.git] / crates / hir_ty / src / tests / traits.rs
index 45a1958e3075dd339f794ceaea78746da33fb7a3..22e0bfc49e3a586919df4a3c54cd9df696c6c4c4 100644 (file)
@@ -6,10 +6,10 @@
 fn infer_await() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
+//- minicore: future
 struct IntFuture;
 
-impl Future for IntFuture {
+impl core::future::Future for IntFuture {
     type Output = u64;
 }
 
@@ -18,15 +18,6 @@ fn test() {
     let v = r.await;
     v;
 } //^ u64
-
-//- /core.rs crate:core
-#[prelude_import] use future::*;
-mod future {
-    #[lang = "future_trait"]
-    trait Future {
-        type Output;
-    }
-}
 "#,
     );
 }
@@ -35,25 +26,14 @@ trait Future {
 fn infer_async() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
-async fn foo() -> u64 {
-            128
-}
+//- minicore: future
+async fn foo() -> u64 { 128 }
 
 fn test() {
     let r = foo();
     let v = r.await;
     v;
 } //^ u64
-
-//- /core.rs crate:core
-#[prelude_import] use future::*;
-mod future {
-    #[lang = "future_trait"]
-    trait Future {
-        type Output;
-    }
-}
 "#,
     );
 }
@@ -62,24 +42,13 @@ trait Future {
 fn infer_desugar_async() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
-async fn foo() -> u64 {
-            128
-}
+//- minicore: future
+async fn foo() -> u64 { 128 }
 
 fn test() {
     let r = foo();
     r;
 } //^ impl Future<Output = u64>
-
-//- /core.rs crate:core
-#[prelude_import] use future::*;
-mod future {
-    trait Future {
-        type Output;
-    }
-}
-
 "#,
     );
 }
@@ -88,7 +57,7 @@ trait Future {
 fn infer_async_block() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
+//- minicore: future, option
 async fn test() {
     let a = async { 42 };
     a;
@@ -100,7 +69,7 @@ async fn test() {
     b;
 //  ^ ()
     let c = async {
-        let y = Option::None;
+        let y = None;
         y
     //  ^ Option<u64>
     };
@@ -108,24 +77,52 @@ async fn test() {
     c;
 //  ^ impl Future<Output = Option<u64>>
 }
+"#,
+    );
+}
 
-enum Option<T> { None, Some(T) }
+#[test]
+fn infer_try() {
+    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 future::*;
-mod future {
-    #[lang = "future_trait"]
-    trait Future {
-        type Output;
+pub mod ops {
+    pub trait Try {
+        type Ok;
+        type Error;
+    }
+}
+
+pub mod result {
+    pub enum Result<O, E> {
+        Ok(O),
+        Err(E)
+    }
+
+    impl<O, E> crate::ops::Try for Result<O, E> {
+        type Ok = O;
+        type Error = E;
     }
 }
 
+pub mod prelude {
+    pub mod rust_2018 {
+        pub use crate::{result::*, ops::*};
+    }
+}
 "#,
     );
 }
 
 #[test]
-fn infer_try() {
+fn infer_try_trait_v2() {
     check_types(
         r#"
 //- /main.rs crate:main deps:core
@@ -136,24 +133,45 @@ fn test() {
 } //^ i32
 
 //- /core.rs crate:core
-#[prelude_import] use ops::*;
 mod ops {
-    trait Try {
-        type Ok;
-        type Error;
+    mod try_trait {
+        pub trait Try: FromResidual {
+            type Output;
+            type Residual;
+        }
+        pub trait FromResidual<R = <Self as Try>::Residual> {}
     }
+
+    pub use self::try_trait::FromResidual;
+    pub use self::try_trait::Try;
+}
+
+mov convert {
+    pub trait From<T> {}
+    impl<T> From<T> for T {}
 }
 
-#[prelude_import] use result::*;
-mod result {
-    enum Result<O, E> {
+pub mod result {
+    use crate::convert::From;
+    use crate::ops::{Try, FromResidual};
+
+    pub enum Infallible {}
+    pub enum Result<O, E> {
         Ok(O),
         Err(E)
     }
 
-    impl<O, E> crate::ops::Try for Result<O, E> {
-        type Ok = O;
-        type Error = E;
+    impl<O, E> Try for Result<O, E> {
+        type Output = O;
+        type Error = Result<Infallible, E>;
+    }
+
+    impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {}
+}
+
+pub mod prelude {
+    pub mod rust_2018 {
+        pub use crate::result::*;
     }
 }
 "#,
@@ -165,6 +183,7 @@ fn infer_for_loop() {
     check_types(
         r#"
 //- /main.rs crate:main deps:core,alloc
+#![no_std]
 use alloc::collections::Vec;
 
 fn test() {
@@ -176,19 +195,24 @@ fn test() {
 }
 
 //- /core.rs crate:core
-#[prelude_import] use iter::*;
-mod iter {
-    trait IntoIterator {
+pub mod iter {
+    pub trait IntoIterator {
         type Item;
     }
 }
+pub mod prelude {
+    pub mod rust_2018 {
+        pub use crate::iter::*;
+    }
+}
 
 //- /alloc.rs crate:alloc deps:core
+#![no_std]
 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 +287,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 +314,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 +343,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 +364,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 +387,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 +416,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 +457,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 +475,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 +493,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 +519,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 +555,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
@@ -646,14 +660,9 @@ pub trait Index<Idx> {
 fn deref_trait() {
     check_types(
         r#"
-#[lang = "deref"]
-trait Deref {
-    type Target;
-    fn deref(&self) -> &Self::Target;
-}
-
+//- minicore: deref
 struct Arc<T>;
-impl<T> Deref for Arc<T> {
+impl<T> core::ops::Deref for Arc<T> {
     type Target = T;
 }
 
@@ -673,16 +682,10 @@ fn test(s: Arc<S>) {
 fn deref_trait_with_inference_var() {
     check_types(
         r#"
-//- /main.rs
-#[lang = "deref"]
-trait Deref {
-    type Target;
-    fn deref(&self) -> &Self::Target;
-}
-
+//- minicore: deref
 struct Arc<T>;
 fn new_arc<T>() -> Arc<T> {}
-impl<T> Deref for Arc<T> {
+impl<T> core::ops::Deref for Arc<T> {
     type Target = T;
 }
 
@@ -703,15 +706,10 @@ fn test() {
 fn deref_trait_infinite_recursion() {
     check_types(
         r#"
-#[lang = "deref"]
-trait Deref {
-    type Target;
-    fn deref(&self) -> &Self::Target;
-}
-
+//- minicore: deref
 struct S;
 
-impl Deref for S {
+impl core::ops::Deref for S {
     type Target = S;
 }
 
@@ -726,14 +724,9 @@ fn test(s: S) {
 fn deref_trait_with_question_mark_size() {
     check_types(
         r#"
-#[lang = "deref"]
-trait Deref {
-    type Target;
-    fn deref(&self) -> &Self::Target;
-}
-
+//- minicore: deref
 struct Arc<T>;
-impl<TDeref for Arc<T> {
+impl<T: ?Sized> core::ops::Deref for Arc<T> {
     type Target = T;
 }
 
@@ -949,27 +942,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 +999,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 +1064,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 +1105,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 +1129,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 +1179,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 +1207,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 +1265,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 +1314,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 +1349,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,23 +1387,29 @@ 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
-            123..124 'f': impl Trait
-            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 '{}': ()
         "#]],
     );
 }
 
 #[test]
-#[ignore]
 fn error_bound_chalk() {
     check_types(
         r#"
@@ -1439,27 +1428,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 '{}': ()
@@ -1504,7 +1492,7 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
 fn impl_trait_assoc_binding_projection_bug() {
     check_types(
         r#"
-//- /main.rs crate:main deps:std
+//- minicore: iterator
 pub trait Language {
     type Kind;
 }
@@ -1524,20 +1512,6 @@ fn api_walkthrough() {
         node.clone();
     }            //^ {unknown}
 }
-
-//- /std.rs crate:std
-#[prelude_import] use iter::*;
-mod iter {
-    trait IntoIterator {
-        type Item;
-    }
-    trait Iterator {
-        type Item;
-    }
-    impl<T: Iterator> IntoIterator for T {
-        type Item = <T as Iterator>::Item;
-    }
-}
 "#,
     );
 }
@@ -1546,18 +1520,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 +1562,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 +1592,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 +1638,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 '{}': ()
@@ -1701,16 +1671,15 @@ fn test() {
 fn fn_trait() {
     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
@@ -1729,37 +1698,36 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
 fn fn_ptr_and_item() {
     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) { loop {} }
-        }
+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> { loop {} }
-        }
+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
@@ -1790,46 +1758,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
@@ -1865,52 +1832,47 @@ fn make_foo_fn() -> Foo {}
 fn closure_1() {
     check_infer_with_mismatches(
         r#"
-        #[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> { loop {} }
-        }
+//- minicore: fn
+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..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
+            86..90 'self': Option<T>
+            92..93 'f': F
+            111..122 '{ loop {} }': Option<U>
+            113..120 'loop {}': !
+            118..120 '{}': ()
+            136..255 '{     ... 1); }': ()
+            146..147 'x': Option<u32>
+            150..162 'Option::Some': Some<u32>(u32) -> Option<u32>
+            150..168 'Option...(1u32)': Option<u32>
+            163..167 '1u32': u32
+            174..175 'x': Option<u32>
+            174..190 'x.map(...v + 1)': Option<u32>
+            180..189 '|v| v + 1': |u32| -> u32
+            181..182 'v': u32
+            184..185 'v': u32
+            184..189 'v + 1': u32
+            188..189 '1': u32
+            196..197 'x': Option<u32>
+            196..212 'x.map(... 1u64)': Option<u64>
+            202..211 '|_v| 1u64': |u32| -> u64
+            203..205 '_v': u32
+            207..211 '1u64': u64
+            222..223 'y': Option<i64>
+            239..240 'x': Option<u32>
+            239..252 'x.map(|_v| 1)': Option<i64>
+            245..251 '|_v| 1': |u32| -> i64
+            246..248 '_v': u32
+            250..251 '1': i64
         "#]],
     );
 }
@@ -1919,38 +1881,63 @@ fn test() {
 fn closure_2() {
     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
         "#]],
     );
 }
@@ -1959,86 +1946,81 @@ fn test<F: FnOnce(u32) -> u64>(f: F) {
 fn closure_as_argument_inference_order() {
     check_infer_with_mismatches(
         r#"
-        #[lang = "fn_once"]
-        trait FnOnce<Args> {
-            type Output;
-        }
+//- minicore: fn
+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 {} }
 
-        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 { loop {} }
-            fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} }
-        }
+    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..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
+            33..34 'x': T
+            39..40 'f': F
+            50..61 '{ loop {} }': U
+            52..59 'loop {}': !
+            57..59 '{}': ()
+            95..96 'f': F
+            101..102 'x': T
+            112..123 '{ loop {} }': U
+            114..121 'loop {}': !
+            119..121 '{}': ()
+            158..162 'self': S
+            210..214 'self': S
+            216..217 'x': T
+            222..223 'f': F
+            233..244 '{ loop {} }': U
+            235..242 'loop {}': !
+            240..242 '{}': ()
+            282..286 'self': S
+            288..289 'f': F
+            294..295 'x': T
+            305..316 '{ loop {} }': U
+            307..314 'loop {}': !
+            312..314 '{}': ()
+            330..489 '{     ... S); }': ()
+            340..342 'x1': u64
+            345..349 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
+            345..368 'foo1(S...hod())': u64
+            350..351 'S': S
+            353..367 '|s| s.method()': |S| -> u64
+            354..355 's': S
+            357..358 's': S
+            357..367 's.method()': u64
+            378..380 'x2': u64
+            383..387 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
+            383..406 'foo2(|...(), S)': u64
+            388..402 '|s| s.method()': |S| -> u64
+            389..390 's': S
+            392..393 's': S
+            392..402 's.method()': u64
+            404..405 'S': S
+            416..418 'x3': u64
+            421..422 'S': S
+            421..446 'S.foo1...hod())': u64
+            428..429 'S': S
+            431..445 '|s| s.method()': |S| -> u64
+            432..433 's': S
+            435..436 's': S
+            435..445 's.method()': u64
+            456..458 'x4': u64
+            461..462 'S': S
+            461..486 'S.foo2...(), S)': u64
+            468..482 '|s| s.method()': |S| -> u64
+            469..470 's': S
+            472..473 's': S
+            472..482 's.method()': u64
+            484..485 'S': S
         "#]],
     );
 }
@@ -2047,11 +2029,7 @@ fn test() {
 fn fn_item_fn_trait() {
     check_types(
         r#"
-#[lang = "fn_once"]
-trait FnOnce<Args> {
-    type Output;
-}
-
+//- minicore: fn
 struct S;
 
 fn foo() -> S {}
@@ -2110,27 +2088,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>
@@ -2366,58 +2343,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! associated_item {
-            (type TokenStream) =>
-                (type TokenStream: 'static;);
-            (type Group) =>
-                (type Group: 'static;);
-            ($($item:tt)*) => ($($item)*;)
+macro_rules! with_api {
+    ($S:ident, $self:ident, $m:ident) => {
+        $m! {
+            TokenStream {
+                fn new() -> $S::TokenStream;
+            },
+            Group {
+            },
         }
-        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 {}': !
@@ -2436,23 +2412,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 {} }': ()
@@ -2493,40 +2468,34 @@ fn test() -> impl Trait<i32> {
 fn assoc_types_from_bounds() {
     check_infer(
         r#"
-        //- /main.rs
-        #[lang = "fn_once"]
-        trait FnOnce<Args> {
-            type Output;
-        }
-
-        trait T {
-            type O;
-        }
+//- minicore: fn
+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 '{ }': ()
-            193..224 '{     ... }); }': ()
-            199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
-            199..221 'f::<()... z; })': ()
-            210..220 '|z| { z; }': |&()| -> ()
-            211..212 'z': &()
-            214..220 '{ z; }': ()
-            216..217 'z': &()
+            72..74 '_v': F
+            117..120 '{ }': ()
+            132..163 '{     ... }); }': ()
+            138..148 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
+            138..160 'f::<()... z; })': ()
+            149..159 '|z| { z; }': |&()| -> ()
+            150..151 'z': &()
+            153..159 '{ z; }': ()
+            155..156 'z': &()
         "#]],
     );
 }
@@ -2560,12 +2529,9 @@ fn test<T: Trait>() {
 fn dyn_trait_through_chalk() {
     check_types(
         r#"
+//- minicore: deref
 struct Box<T> {}
-#[lang = "deref"]
-trait Deref {
-    type Target;
-}
-impl<T> Deref for Box<T> {
+impl<T> core::ops::Deref for Box<T> {
     type Target = T;
 }
 trait Trait {
@@ -2602,117 +2568,106 @@ fn test() {
 fn iterator_chain() {
     check_infer_with_mismatches(
         r#"
-        //- /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::*;
-
-        pub trait Iterator {
-            type Item;
+//- minicore: fn, option
+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
-            317..328 '{ loop {} }': FilterMap<Self, F>
-            319..326 'loop {}': !
-            324..326 '{}': ()
-            349..353 'self': Self
-            355..356 'f': F
-            405..416 '{ loop {} }': ()
-            407..414 'loop {}': !
-            412..414 '{}': ()
-            525..529 'self': Self
-            854..858 'self': I
-            865..885 '{     ...     }': I
-            875..879 'self': I
-            944..955 '{ loop {} }': Vec<T>
-            946..953 'loop {}': !
-            951..953 '{}': ()
-            1142..1269 '{     ... }); }': ()
-            1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
-            1148..1165 'Vec::<...:new()': Vec<i32>
-            1148..1177 'Vec::<...iter()': IntoIter<i32>
-            1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
-            1148..1266 'Vec::<... y; })': ()
-            1194..1239 '|x| if...None }': |i32| -> Option<u32>
-            1195..1196 'x': i32
-            1198..1239 'if x >...None }': Option<u32>
-            1201..1202 'x': i32
-            1201..1206 'x > 0': bool
-            1205..1206 '0': i32
-            1207..1225 '{ Some...u32) }': Option<u32>
-            1209..1213 'Some': Some<u32>(u32) -> Option<u32>
-            1209..1223 'Some(x as u32)': Option<u32>
-            1214..1215 'x': i32
-            1214..1222 'x as u32': u32
-            1231..1239 '{ None }': Option<u32>
-            1233..1237 'None': Option<u32>
-            1255..1265 '|y| { y; }': |u32| -> ()
-            1256..1257 'y': u32
-            1259..1265 '{ y; }': ()
-            1261..1262 'y': u32
+            61..65 'self': Self
+            67..68 'f': F
+            152..163 '{ loop {} }': FilterMap<Self, F>
+            154..161 'loop {}': !
+            159..161 '{}': ()
+            184..188 'self': Self
+            190..191 'f': F
+            240..251 '{ loop {} }': ()
+            242..249 'loop {}': !
+            247..249 '{}': ()
+            360..364 'self': Self
+            689..693 'self': I
+            700..720 '{     ...     }': I
+            710..714 'self': I
+            779..790 '{ loop {} }': Vec<T>
+            781..788 'loop {}': !
+            786..788 '{}': ()
+            977..1104 '{     ... }); }': ()
+            983..998 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
+            983..1000 'Vec::<...:new()': Vec<i32>
+            983..1012 'Vec::<...iter()': IntoIter<i32>
+            983..1075 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
+            983..1101 'Vec::<... y; })': ()
+            1029..1074 '|x| if...None }': |i32| -> Option<u32>
+            1030..1031 'x': i32
+            1033..1074 'if x >...None }': Option<u32>
+            1036..1037 'x': i32
+            1036..1041 'x > 0': bool
+            1040..1041 '0': i32
+            1042..1060 '{ Some...u32) }': Option<u32>
+            1044..1048 'Some': Some<u32>(u32) -> Option<u32>
+            1044..1058 'Some(x as u32)': Option<u32>
+            1049..1050 'x': i32
+            1049..1057 'x as u32': u32
+            1066..1074 '{ None }': Option<u32>
+            1068..1072 'None': Option<u32>
+            1090..1100 '|y| { y; }': |u32| -> ()
+            1091..1092 'y': u32
+            1094..1100 '{ y; }': ()
+            1096..1097 'y': u32
         "#]],
     );
 }
@@ -2753,14 +2708,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 '{}': ()
@@ -2777,23 +2731,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(); }': ()
@@ -2817,24 +2770,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}
@@ -2858,18 +2810,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()
@@ -2890,19 +2841,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 }': ()
@@ -2972,19 +2922,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>
@@ -3005,94 +2954,71 @@ fn foo() {
 fn infer_fn_trait_arg() {
     check_infer_with_mismatches(
         r#"
-        //- /lib.rs deps:std
-
-        #[lang = "fn_once"]
-        pub trait FnOnce<Args> {
-            type Output;
-
-            extern "rust-call" fn call_once(&self, args: Args) -> Self::Output;
-        }
-
-        #[lang = "fn"]
-        pub trait Fn<Args>:FnOnce<Args> {
-            extern "rust-call" fn call(&self, args: Args) -> Self::Output;
-        }
-
-        enum Option<T> {
-            None,
-            Some(T)
-        }
-
-        fn foo<F, T>(f: F) -> T
-        where
-            F: Fn(Option<i32>) -> T,
-        {
-            let s = None;
-            f(s)
-        }
-        "#,
+//- minicore: fn, option
+fn foo<F, T>(f: F) -> T
+where
+    F: Fn(Option<i32>) -> T,
+{
+    let s = None;
+    f(s)
+}
+"#,
         expect![[r#"
-            101..105 'self': &Self
-            107..111 'args': Args
-            220..224 'self': &Self
-            226..230 'args': Args
-            313..314 'f': F
-            359..389 '{     ...f(s) }': T
-            369..370 's': Option<i32>
-            373..377 'None': Option<i32>
-            383..384 'f': F
-            383..387 'f(s)': T
-            385..386 's': Option<i32>
+            13..14 'f': F
+            59..89 '{     ...f(s) }': T
+            69..70 's': Option<i32>
+            73..77 'None': Option<i32>
+            83..84 'f': F
+            83..87 'f(s)': T
+            85..86 's': Option<i32>
         "#]],
     );
 }
 
 #[test]
 fn infer_box_fn_arg() {
-    // The type mismatch is a bug
+    // 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
@@ -3111,10 +3037,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<|_| -> ()>
+            549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
         "#]],
     );
 }
@@ -3123,17 +3049,7 @@ fn foo() {
 fn infer_dyn_fn_output() {
     check_types(
         r#"
-#[lang = "fn_once"]
-pub trait FnOnce<Args> {
-    type Output;
-    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
-#[lang = "fn"]
-pub trait Fn<Args>: FnOnce<Args> {
-    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
-}
-
+//- minicore: fn
 fn foo() {
     let f: &dyn Fn() -> i32;
     f();
@@ -3146,12 +3062,7 @@ fn foo() {
 fn infer_dyn_fn_once_output() {
     check_types(
         r#"
-#[lang = "fn_once"]
-pub trait FnOnce<Args> {
-    type Output;
-    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
+//- minicore: fn
 fn foo() {
     let f: dyn FnOnce() -> i32;
     f();
@@ -3258,8 +3169,7 @@ fn inner() {
         ().method();
       //^^^^^^^^^^^ u8
     }
-}
-        "#,
+}"#,
         expect![[r#"
             46..50 'self': &Self
             58..63 '{ 0 }': u8
@@ -3313,8 +3223,7 @@ fn f() {
     fn inner() -> S {
         let s = inner();
     }
-}
-        "#,
+}"#,
         expect![[r#"
             17..73 '{     ...   } }': ()
             39..71 '{     ...     }': ()
@@ -3349,8 +3258,7 @@ fn test() {
     let x = A;
     let y = A;
     let r = x.do_op(y);
-}
-        "#,
+}"#,
         expect![[r#"
             63..67 'self': Self
             69..72 'rhs': RHS
@@ -3370,3 +3278,363 @@ fn test() {
         "#]],
     )
 }
+
+#[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#"
+//- minicore: fn
+fn test<F: FnOnce()>(f: F) {
+    let _: () = f();
+}"#,
+        expect![[r#"
+            21..22 'f': F
+            27..51 '{     ...f(); }': ()
+            37..38 '_': ()
+            45..46 'f': F
+            45..48 '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
+        "#]],
+    );
+}
+
+#[test]
+fn infer_async_ret_type() {
+    check_types(
+        r#"
+//- minicore: future, result
+struct Fooey;
+
+impl Fooey {
+    fn collect<B: Convert>(self) -> B {
+        B::new()
+    }
+}
+
+trait Convert {
+    fn new() -> Self;
+}
+impl Convert for u32 {
+    fn new() -> Self {
+        0
+    }
+}
+
+async fn get_accounts() -> Result<u32, ()> {
+    let ret = Fooey.collect();
+    //                      ^ u32
+    Ok(ret)
+}
+"#,
+    );
+}
+
+#[test]
+fn local_impl_1() {
+    check_types(
+        r#"
+trait Trait<T> {
+    fn foo(&self) -> T;
+}
+
+fn test() {
+    struct S;
+    impl Trait<u32> for S {
+        fn foo(&self) { 0 }
+    }
+
+    S.foo();
+ // ^^^^^^^ u32
+}
+"#,
+    );
+}
+
+#[test]
+fn local_impl_2() {
+    check_types(
+        r#"
+struct S;
+
+fn test() {
+    trait Trait<T> {
+        fn foo(&self) -> T;
+    }
+    impl Trait<u32> for S {
+        fn foo(&self) { 0 }
+    }
+
+    S.foo();
+ // ^^^^^^^ u32
+}
+"#,
+    );
+}
+
+#[test]
+fn local_impl_3() {
+    check_types(
+        r#"
+trait Trait<T> {
+    fn foo(&self) -> T;
+}
+
+fn test() {
+    struct S1;
+    {
+        struct S2;
+
+        impl Trait<S1> for S2 {
+            fn foo(&self) { S1 }
+        }
+
+        S2.foo();
+     // ^^^^^^^^ S1
+    }
+}
+"#,
+    );
+}