#[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);
);
}
+#[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(
"#]],
);
}
+
+#[test]
+fn method_resolution_foreign_opaque_type() {
+ check_infer(
+ r#"
+ extern "C" {
+ type S;
+ fn f() -> &'static S;
+ }
+
+ impl S {
+ fn foo(&self) -> bool {
+ true
+ }
+ }
+
+ fn test() {
+ let s = unsafe { f() };
+ s.foo();
+ }
+ "#,
+ expect![[r#"
+ 75..79 'self': &S
+ 89..109 '{ ... }': bool
+ 99..103 'true': bool
+ 123..167 '{ ...o(); }': ()
+ 133..134 's': &S
+ 137..151 'unsafe { f() }': &S
+ 144..151 '{ f() }': &S
+ 146..147 'f': fn f() -> &S
+ 146..149 'f()': &S
+ 157..158 's': &S
+ 157..164 's.foo()': bool
+ "#]],
+ );
+}
+
+#[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
+}
+ "#,
+ );
+}