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 {} }}
}
}
}
"#,
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
"#]],
);
}
#[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_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
+}
+ "#,
+ );
+}