]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/tests/method_resolution.rs
Merge #9007
[rust.git] / crates / hir_ty / src / tests / method_resolution.rs
index 596d4f182602c5299f084b6ebe6400dd70190ec4..a4c132bc5f206143e0c85543f6346a184fd89887 100644 (file)
@@ -108,16 +108,16 @@ fn infer_associated_method_with_modules() {
     check_infer(
         r#"
         mod a {
-            pub struct A;
+            struct A;
             impl A { pub fn thing() -> A { A {} }}
         }
 
         mod b {
-            pub struct B;
+            struct B;
             impl B { pub fn thing() -> u32 { 99 }}
 
-            pub mod c {
-                pub struct C;
+            mod c {
+                struct C;
                 impl C { pub fn thing() -> C { C {} }}
             }
         }
@@ -130,22 +130,22 @@ fn test() {
         }
         "#,
         expect![[r#"
-            59..67 '{ A {} }': a::A
-            61..65 'A {}': a::A
-            133..139 '{ 99 }': u32
-            135..137 '99': u32
-            217..225 '{ C {} }': c::C
-            219..223 'C {}': c::C
-            256..340 '{     ...g(); }': ()
-            266..267 'x': a::A
-            270..281 'a::A::thing': fn thing() -> A
-            270..283 'a::A::thing()': a::A
-            293..294 'y': u32
-            297..308 'b::B::thing': fn thing() -> u32
-            297..310 'b::B::thing()': u32
-            320..321 'z': c::C
-            324..335 'c::C::thing': fn thing() -> C
-            324..337 'c::C::thing()': c::C
+            55..63 '{ A {} }': A
+            57..61 'A {}': A
+            125..131 '{ 99 }': u32
+            127..129 '99': u32
+            201..209 '{ C {} }': C
+            203..207 'C {}': C
+            240..324 '{     ...g(); }': ()
+            250..251 'x': A
+            254..265 'a::A::thing': fn thing() -> A
+            254..267 'a::A::thing()': A
+            277..278 'y': u32
+            281..292 'b::B::thing': fn thing() -> u32
+            281..294 'b::B::thing()': u32
+            304..305 'z': C
+            308..319 'c::C::thing': fn thing() -> C
+            308..321 'c::C::thing()': C
         "#]],
     );
 }
@@ -913,7 +913,7 @@ impl<T, U: From<T>> Into<U> for T {}
 
 #[test]
 fn method_resolution_overloaded_method() {
-    test_utils::mark::check!(impl_self_type_match_without_receiver);
+    cov_mark::check!(impl_self_type_match_without_receiver);
     check_types(
         r#"
 struct Wrapper<T>(T);
@@ -955,6 +955,51 @@ fn foo() {}
     );
 }
 
+#[test]
+fn super_trait_impl_return_trait_method_resolution() {
+    check_infer(
+        r#"
+        trait Base {
+            fn foo(self) -> usize;
+        }
+
+        trait Super : Base {}
+
+        fn base1() -> impl Base { loop {} }
+        fn super1() -> impl Super { loop {} }
+
+        fn test(base2: impl Base, super2: impl Super) {
+            base1().foo();
+            super1().foo();
+            base2.foo();
+            super2.foo();
+        }
+        "#,
+        expect![[r#"
+            24..28 'self': Self
+            90..101 '{ loop {} }': !
+            92..99 'loop {}': !
+            97..99 '{}': ()
+            128..139 '{ loop {} }': !
+            130..137 'loop {}': !
+            135..137 '{}': ()
+            149..154 'base2': impl Base
+            167..173 'super2': impl Super
+            187..264 '{     ...o(); }': ()
+            193..198 'base1': fn base1() -> impl Base
+            193..200 'base1()': impl Base
+            193..206 'base1().foo()': usize
+            212..218 'super1': fn super1() -> impl Super
+            212..220 'super1()': impl Super
+            212..226 'super1().foo()': usize
+            232..237 'base2': impl Base
+            232..243 'base2.foo()': usize
+            249..255 'super2': impl Super
+            249..261 'super2.foo()': usize
+        "#]],
+    );
+}
+
 #[test]
 fn method_resolution_non_parameter_type() {
     check_types(
@@ -1087,3 +1132,220 @@ fn test() {
         "#]],
     );
 }
+
+#[test]
+fn method_with_allocator_box_self_type() {
+    check_types(
+        r#"
+struct Slice<T> {}
+struct Box<T, A> {}
+
+impl<T> Slice<T> {
+    pub fn into_vec<A>(self: Box<Self, A>) { }
+}
+
+fn main() {
+    let foo: Slice<u32>;
+    (foo.into_vec()); // we don't actually support arbitrary self types, but we shouldn't crash at least
+} //^ {unknown}
+"#,
+    );
+}
+
+#[test]
+fn method_on_dyn_impl() {
+    check_types(
+        r#"
+trait Foo {}
+
+impl Foo for u32 {}
+impl dyn Foo + '_ {
+    pub fn dyn_foo(&self) -> u32 {
+        0
+    }
+}
+
+fn main() {
+    let f = &42u32 as &dyn Foo;
+    f.dyn_foo();
+  // ^u32
+}
+"#,
+    );
+}
+
+#[test]
+fn autoderef_visibility_field() {
+    check_infer(
+        r#"
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+    fn deref(&self) -> &Self::Target;
+}
+mod a {
+    pub struct Foo(pub char);
+    pub struct Bar(i32);
+    impl Bar {
+        pub fn new() -> Self {
+            Self(0)
+        }
+    }
+    impl super::Deref for Bar {
+        type Target = Foo;
+        fn deref(&self) -> &Foo {
+            &Foo('z')
+        }
+    }
+}
+mod b {
+    fn foo() {
+        let x = super::a::Bar::new().0;
+    }
+}
+        "#,
+        expect![[r#"
+            67..71 'self': &Self
+            200..231 '{     ...     }': Bar
+            214..218 'Self': Bar(i32) -> Bar
+            214..221 'Self(0)': Bar
+            219..220 '0': i32
+            315..319 'self': &Bar
+            329..362 '{     ...     }': &Foo
+            343..352 '&Foo('z')': &Foo
+            344..347 'Foo': Foo(char) -> Foo
+            344..352 'Foo('z')': Foo
+            348..351 ''z'': char
+            392..439 '{     ...     }': ()
+            406..407 'x': char
+            410..428 'super:...r::new': fn new() -> Bar
+            410..430 'super:...:new()': Bar
+            410..432 'super:...ew().0': char
+        "#]],
+    )
+}
+
+#[test]
+fn autoderef_visibility_method() {
+    cov_mark::check!(autoderef_candidate_not_visible);
+    check_infer(
+        r#"
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+    fn deref(&self) -> &Self::Target;
+}
+mod a {
+    pub struct Foo(pub char);
+    impl Foo {
+        pub fn mango(&self) -> char {
+            self.0
+        }
+    }
+    pub struct Bar(i32);
+    impl Bar {
+        pub fn new() -> Self {
+            Self(0)
+        }
+        fn mango(&self) -> i32 {
+            self.0
+        }
+    }
+    impl super::Deref for Bar {
+        type Target = Foo;
+        fn deref(&self) -> &Foo {
+            &Foo('z')
+        }
+    }
+}
+mod b {
+    fn foo() {
+        let x = super::a::Bar::new().mango();
+    }
+}
+        "#,
+        expect![[r#"
+            67..71 'self': &Self
+            168..172 'self': &Foo
+            182..212 '{     ...     }': char
+            196..200 'self': &Foo
+            196..202 'self.0': char
+            288..319 '{     ...     }': Bar
+            302..306 'Self': Bar(i32) -> Bar
+            302..309 'Self(0)': Bar
+            307..308 '0': i32
+            338..342 'self': &Bar
+            351..381 '{     ...     }': i32
+            365..369 'self': &Bar
+            365..371 'self.0': i32
+            465..469 'self': &Bar
+            479..512 '{     ...     }': &Foo
+            493..502 '&Foo('z')': &Foo
+            494..497 'Foo': Foo(char) -> Foo
+            494..502 'Foo('z')': Foo
+            498..501 ''z'': char
+            542..595 '{     ...     }': ()
+            556..557 'x': char
+            560..578 'super:...r::new': fn new() -> Bar
+            560..580 'super:...:new()': Bar
+            560..588 'super:...ango()': char
+        "#]],
+    )
+}
+
+#[test]
+fn trait_impl_in_unnamed_const() {
+    check_types(
+        r#"
+struct S;
+
+trait Tr {
+    fn method(&self) -> u16;
+}
+
+const _: () = {
+    impl Tr for S {}
+};
+
+fn f() {
+    S.method();
+  //^^^^^^^^^^ u16
+}
+    "#,
+    );
+}
+
+#[test]
+fn inherent_impl_in_unnamed_const() {
+    check_types(
+        r#"
+struct S;
+
+const _: () = {
+    impl S {
+        fn method(&self) -> u16 { 0 }
+
+        pub(super) fn super_method(&self) -> u16 { 0 }
+
+        pub(crate) fn crate_method(&self) -> u16 { 0 }
+
+        pub fn pub_method(&self) -> u16 { 0 }
+    }
+};
+
+fn f() {
+    S.method();
+  //^^^^^^^^^^ u16
+
+    S.super_method();
+  //^^^^^^^^^^^^^^^^ u16
+
+    S.crate_method();
+  //^^^^^^^^^^^^^^^^ u16
+
+    S.pub_method();
+  //^^^^^^^^^^^^^^ u16
+}
+    "#,
+    );
+}