2020-08-21 11:19:31 +00:00
|
|
|
use expect_test::expect;
|
2020-06-29 15:22:47 +00:00
|
|
|
|
2021-07-09 17:12:56 +00:00
|
|
|
use crate::tests::check;
|
|
|
|
|
2022-03-23 18:18:12 +00:00
|
|
|
use super::{check_infer, check_no_mismatches, check_types};
|
2019-12-03 12:38:54 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_slice_method() {
|
2022-04-02 13:32:40 +00:00
|
|
|
check_types(
|
2020-07-21 10:08:55 +00:00
|
|
|
r#"
|
2022-04-02 13:32:40 +00:00
|
|
|
impl<T> [T] {
|
|
|
|
fn foo(&self) -> T {
|
|
|
|
loop {}
|
|
|
|
}
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
|
2022-04-02 13:32:40 +00:00
|
|
|
fn test(x: &[u8]) {
|
|
|
|
<[_]>::foo(x);
|
|
|
|
//^^^^^^^^^^^^^ u8
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
"#,
|
2022-04-02 13:32:40 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn cross_crate_primitive_method() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
//- /main.rs crate:main deps:other_crate
|
|
|
|
fn test() {
|
|
|
|
let x = 1f32;
|
|
|
|
x.foo();
|
|
|
|
} //^^^^^^^ f32
|
|
|
|
|
|
|
|
//- /lib.rs crate:other_crate
|
|
|
|
mod foo {
|
|
|
|
impl f32 {
|
|
|
|
pub fn foo(self) -> f32 { 0. }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-08-31 12:15:39 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_array_inherent_impl() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
2022-04-02 13:32:40 +00:00
|
|
|
impl<T, const N: usize> [T; N] {
|
|
|
|
fn foo(&self) -> T {
|
|
|
|
loop {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn test(x: &[u8; 0]) {
|
|
|
|
<[_; 0]>::foo(x);
|
|
|
|
//^^^^^^^^^^^^^^^^ u8
|
|
|
|
}
|
2021-08-31 12:15:39 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_struct() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
struct A { x: u32 }
|
|
|
|
|
|
|
|
impl A {
|
|
|
|
fn new() -> A {
|
|
|
|
A { x: 0 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn test() {
|
|
|
|
let a = A::new();
|
|
|
|
a.x;
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
48..74 '{ ... }': A
|
|
|
|
58..68 'A { x: 0 }': A
|
|
|
|
65..66 '0': u32
|
|
|
|
87..121 '{ ...a.x; }': ()
|
|
|
|
97..98 'a': A
|
|
|
|
101..107 'A::new': fn new() -> A
|
|
|
|
101..109 'A::new()': A
|
|
|
|
115..116 'a': A
|
|
|
|
115..118 'a.x': u32
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-12-14 07:34:57 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_struct_in_local_scope() {
|
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
fn mismatch() {
|
|
|
|
struct A;
|
|
|
|
|
|
|
|
impl A {
|
|
|
|
fn from(_: i32, _: i32) -> Self {
|
|
|
|
A
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let _a = A::from(1, 2);
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
14..146 '{ ... 2); }': ()
|
|
|
|
125..127 '_a': A
|
|
|
|
130..137 'A::from': fn from(i32, i32) -> A
|
|
|
|
130..143 'A::from(1, 2)': A
|
|
|
|
138..139 '1': i32
|
|
|
|
141..142 '2': i32
|
|
|
|
60..61 '_': i32
|
|
|
|
68..69 '_': i32
|
|
|
|
84..109 '{ ... }': A
|
|
|
|
98..99 'A': A
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_enum() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
enum A { B, C }
|
|
|
|
|
|
|
|
impl A {
|
|
|
|
pub fn b() -> A {
|
|
|
|
A::B
|
|
|
|
}
|
|
|
|
pub fn c() -> A {
|
|
|
|
A::C
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn test() {
|
|
|
|
let a = A::b();
|
|
|
|
a;
|
|
|
|
let c = A::c();
|
|
|
|
c;
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
46..66 '{ ... }': A
|
|
|
|
56..60 'A::B': A
|
|
|
|
87..107 '{ ... }': A
|
|
|
|
97..101 'A::C': A
|
|
|
|
120..177 '{ ... c; }': ()
|
|
|
|
130..131 'a': A
|
|
|
|
134..138 'A::b': fn b() -> A
|
|
|
|
134..140 'A::b()': A
|
|
|
|
146..147 'a': A
|
|
|
|
157..158 'c': A
|
|
|
|
161..165 'A::c': fn c() -> A
|
|
|
|
161..167 'A::c()': A
|
|
|
|
173..174 'c': A
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_with_modules() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
mod a {
|
|
|
|
struct A;
|
|
|
|
impl A { pub fn thing() -> A { A {} }}
|
|
|
|
}
|
|
|
|
|
|
|
|
mod b {
|
|
|
|
struct B;
|
|
|
|
impl B { pub fn thing() -> u32 { 99 }}
|
|
|
|
|
|
|
|
mod c {
|
|
|
|
struct C;
|
|
|
|
impl C { pub fn thing() -> C { C {} }}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
use b::c;
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let x = a::A::thing();
|
|
|
|
let y = b::B::thing();
|
|
|
|
let z = c::C::thing();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
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
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_generics() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
struct Gen<T> {
|
|
|
|
val: T
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Gen<T> {
|
|
|
|
pub fn make(val: T) -> Gen<T> {
|
|
|
|
Gen { val }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let a = Gen::make(0u32);
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
63..66 'val': T
|
|
|
|
81..108 '{ ... }': Gen<T>
|
|
|
|
91..102 'Gen { val }': Gen<T>
|
|
|
|
97..100 'val': T
|
|
|
|
122..154 '{ ...32); }': ()
|
|
|
|
132..133 'a': Gen<u32>
|
|
|
|
136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32>
|
|
|
|
136..151 'Gen::make(0u32)': Gen<u32>
|
|
|
|
146..150 '0u32': u32
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_generics_without_args() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
struct Gen<T> {
|
|
|
|
val: T
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Gen<T> {
|
|
|
|
pub fn make() -> Gen<T> {
|
|
|
|
loop { }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let a = Gen::<u32>::make();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
75..99 '{ ... }': Gen<T>
|
|
|
|
85..93 'loop { }': !
|
|
|
|
90..93 '{ }': ()
|
|
|
|
113..148 '{ ...e(); }': ()
|
|
|
|
123..124 'a': Gen<u32>
|
|
|
|
127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32>
|
|
|
|
127..145 'Gen::<...make()': Gen<u32>
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_associated_method_generics_2_type_params_without_args() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
struct Gen<T, U> {
|
|
|
|
val: T,
|
|
|
|
val2: U,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Gen<u32, T> {
|
|
|
|
pub fn make() -> Gen<u32,T> {
|
|
|
|
loop { }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let a = Gen::<u32, u64>::make();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
101..125 '{ ... }': Gen<u32, T>
|
|
|
|
111..119 'loop { }': !
|
|
|
|
116..119 '{ }': ()
|
|
|
|
139..179 '{ ...e(); }': ()
|
|
|
|
149..150 'a': Gen<u32, u64>
|
|
|
|
153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64>
|
|
|
|
153..176 'Gen::<...make()': Gen<u32, u64>
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn cross_crate_associated_method_call() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
//- /main.rs crate:main deps:other_crate
|
|
|
|
fn test() {
|
|
|
|
let x = other_crate::foo::S::thing();
|
2020-06-29 15:22:47 +00:00
|
|
|
x;
|
|
|
|
} //^ i128
|
2019-12-03 12:38:54 +00:00
|
|
|
|
|
|
|
//- /lib.rs crate:other_crate
|
2021-07-21 15:51:56 +00:00
|
|
|
pub mod foo {
|
|
|
|
pub struct S;
|
2019-12-03 12:38:54 +00:00
|
|
|
impl S {
|
2021-12-14 07:57:58 +00:00
|
|
|
pub fn thing() -> i128 { 0 }
|
2019-12-03 12:38:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_method_simple() {
|
|
|
|
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
2021-06-20 14:37:50 +00:00
|
|
|
check_types(
|
2020-07-21 10:08:55 +00:00
|
|
|
r#"
|
2021-06-20 14:37:50 +00:00
|
|
|
trait Trait1 {
|
|
|
|
fn method(&self) -> u32;
|
|
|
|
}
|
|
|
|
struct S1;
|
|
|
|
impl Trait1 for S1 {}
|
|
|
|
trait Trait2 {
|
|
|
|
fn method(&self) -> i128;
|
|
|
|
}
|
|
|
|
struct S2;
|
|
|
|
impl Trait2 for S2 {}
|
|
|
|
fn test() {
|
|
|
|
S1.method();
|
|
|
|
//^^^^^^^^^^^ u32
|
|
|
|
S2.method(); // -> i128
|
|
|
|
//^^^^^^^^^^^ i128
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
"#,
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_method_scoped() {
|
|
|
|
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
2021-06-20 14:37:50 +00:00
|
|
|
check_types(
|
2020-07-21 10:08:55 +00:00
|
|
|
r#"
|
2021-06-20 14:37:50 +00:00
|
|
|
struct S;
|
|
|
|
mod foo {
|
|
|
|
pub trait Trait1 {
|
|
|
|
fn method(&self) -> u32;
|
|
|
|
}
|
|
|
|
impl Trait1 for super::S {}
|
|
|
|
}
|
|
|
|
mod bar {
|
|
|
|
pub trait Trait2 {
|
|
|
|
fn method(&self) -> i128;
|
|
|
|
}
|
|
|
|
impl Trait2 for super::S {}
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
|
2021-06-20 14:37:50 +00:00
|
|
|
mod foo_test {
|
|
|
|
use super::S;
|
|
|
|
use super::foo::Trait1;
|
|
|
|
fn test() {
|
|
|
|
S.method();
|
|
|
|
//^^^^^^^^^^ u32
|
|
|
|
}
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
|
2021-06-20 14:37:50 +00:00
|
|
|
mod bar_test {
|
|
|
|
use super::S;
|
|
|
|
use super::bar::Trait2;
|
|
|
|
fn test() {
|
|
|
|
S.method();
|
|
|
|
//^^^^^^^^^^ i128
|
|
|
|
}
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
"#,
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_method_generic_1() {
|
|
|
|
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
2021-06-20 14:37:50 +00:00
|
|
|
check_types(
|
2020-07-21 10:08:55 +00:00
|
|
|
r#"
|
2021-06-20 14:37:50 +00:00
|
|
|
trait Trait<T> {
|
|
|
|
fn method(&self) -> T;
|
|
|
|
}
|
|
|
|
struct S;
|
|
|
|
impl Trait<u32> for S {}
|
|
|
|
fn test() {
|
|
|
|
S.method();
|
|
|
|
//^^^^^^^^^^ u32
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
"#,
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_method_generic_more_params() {
|
|
|
|
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
2021-06-20 14:37:50 +00:00
|
|
|
check_types(
|
2020-07-21 10:08:55 +00:00
|
|
|
r#"
|
2021-06-20 14:37:50 +00:00
|
|
|
trait Trait<T1, T2, T3> {
|
|
|
|
fn method1(&self) -> (T1, T2, T3);
|
|
|
|
fn method2(&self) -> (T3, T2, T1);
|
|
|
|
}
|
|
|
|
struct S1;
|
|
|
|
impl Trait<u8, u16, u32> for S1 {}
|
|
|
|
struct S2;
|
|
|
|
impl<T> Trait<i8, i16, T> for S2 {}
|
|
|
|
fn test() {
|
|
|
|
S1.method1();
|
|
|
|
//^^^^^^^^^^^^ (u8, u16, u32)
|
|
|
|
S1.method2();
|
|
|
|
//^^^^^^^^^^^^ (u32, u16, u8)
|
|
|
|
S2.method1();
|
|
|
|
//^^^^^^^^^^^^ (i8, i16, {unknown})
|
|
|
|
S2.method2();
|
|
|
|
//^^^^^^^^^^^^ ({unknown}, i16, i8)
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
"#,
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_method_generic_2() {
|
|
|
|
// the trait implementation is intentionally incomplete -- it shouldn't matter
|
2021-06-20 14:37:50 +00:00
|
|
|
check_types(
|
2020-07-21 10:08:55 +00:00
|
|
|
r#"
|
2021-06-20 14:37:50 +00:00
|
|
|
trait Trait<T> {
|
|
|
|
fn method(&self) -> T;
|
|
|
|
}
|
|
|
|
struct S<T>(T);
|
|
|
|
impl<U> Trait<U> for S<U> {}
|
|
|
|
fn test() {
|
|
|
|
S(1u32).method();
|
|
|
|
//^^^^^^^^^^^^^^^^ u32
|
|
|
|
}
|
2020-07-21 10:08:55 +00:00
|
|
|
"#,
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_assoc_method() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Default {
|
|
|
|
fn default() -> Self;
|
|
|
|
}
|
|
|
|
struct S;
|
|
|
|
impl Default for S {}
|
|
|
|
fn test() {
|
|
|
|
let s1: S = Default::default();
|
|
|
|
let s2 = S::default();
|
|
|
|
let s3 = <S as Default>::default();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
86..192 '{ ...t(); }': ()
|
|
|
|
96..98 's1': S
|
|
|
|
104..120 'Defaul...efault': fn default<S>() -> S
|
|
|
|
104..122 'Defaul...ault()': S
|
|
|
|
132..134 's2': S
|
|
|
|
137..147 'S::default': fn default<S>() -> S
|
|
|
|
137..149 'S::default()': S
|
|
|
|
159..161 's3': S
|
|
|
|
164..187 '<S as ...efault': fn default<S>() -> S
|
|
|
|
164..189 '<S as ...ault()': S
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_assoc_method_generics_1() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait<T> {
|
|
|
|
fn make() -> T;
|
|
|
|
}
|
|
|
|
struct S;
|
|
|
|
impl Trait<u32> for S {}
|
|
|
|
struct G<T>;
|
|
|
|
impl<T> Trait<T> for G<T> {}
|
|
|
|
fn test() {
|
|
|
|
let a = S::make();
|
|
|
|
let b = G::<u64>::make();
|
|
|
|
let c: f64 = G::make();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
126..210 '{ ...e(); }': ()
|
|
|
|
136..137 'a': u32
|
|
|
|
140..147 'S::make': fn make<S, u32>() -> u32
|
|
|
|
140..149 'S::make()': u32
|
|
|
|
159..160 'b': u64
|
|
|
|
163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64
|
|
|
|
163..179 'G::<u6...make()': u64
|
|
|
|
189..190 'c': f64
|
|
|
|
198..205 'G::make': fn make<G<f64>, f64>() -> f64
|
|
|
|
198..207 'G::make()': f64
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_assoc_method_generics_2() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait<T> {
|
|
|
|
fn make<U>() -> (T, U);
|
|
|
|
}
|
|
|
|
struct S;
|
|
|
|
impl Trait<u32> for S {}
|
|
|
|
struct G<T>;
|
|
|
|
impl<T> Trait<T> for G<T> {}
|
|
|
|
fn test() {
|
|
|
|
let a = S::make::<i64>();
|
|
|
|
let b: (_, i64) = S::make();
|
|
|
|
let c = G::<u32>::make::<i64>();
|
|
|
|
let d: (u32, _) = G::make::<i64>();
|
|
|
|
let e: (u32, i64) = G::make();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
134..312 '{ ...e(); }': ()
|
|
|
|
144..145 'a': (u32, i64)
|
|
|
|
148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64)
|
|
|
|
148..164 'S::mak...i64>()': (u32, i64)
|
|
|
|
174..175 'b': (u32, i64)
|
|
|
|
188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64)
|
|
|
|
188..197 'S::make()': (u32, i64)
|
|
|
|
207..208 'c': (u32, i64)
|
|
|
|
211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
|
|
|
|
211..234 'G::<u3...i64>()': (u32, i64)
|
|
|
|
244..245 'd': (u32, i64)
|
|
|
|
258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
|
|
|
|
258..274 'G::mak...i64>()': (u32, i64)
|
|
|
|
284..285 'e': (u32, i64)
|
|
|
|
300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64)
|
|
|
|
300..309 'G::make()': (u32, i64)
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_assoc_method_generics_3() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait<T> {
|
|
|
|
fn make() -> (Self, T);
|
|
|
|
}
|
|
|
|
struct S<T>;
|
|
|
|
impl Trait<i64> for S<i32> {}
|
|
|
|
fn test() {
|
|
|
|
let a = S::make();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
100..126 '{ ...e(); }': ()
|
|
|
|
110..111 'a': (S<i32>, i64)
|
|
|
|
114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64)
|
|
|
|
114..123 'S::make()': (S<i32>, i64)
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_assoc_method_generics_4() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait<T> {
|
|
|
|
fn make() -> (Self, T);
|
|
|
|
}
|
|
|
|
struct S<T>;
|
|
|
|
impl Trait<i64> for S<u64> {}
|
|
|
|
impl Trait<i32> for S<u32> {}
|
|
|
|
fn test() {
|
|
|
|
let a: (S<u64>, _) = S::make();
|
|
|
|
let b: (_, i32) = S::make();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
130..202 '{ ...e(); }': ()
|
|
|
|
140..141 'a': (S<u64>, i64)
|
|
|
|
157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64)
|
|
|
|
157..166 'S::make()': (S<u64>, i64)
|
|
|
|
176..177 'b': (S<u32>, i32)
|
|
|
|
190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32)
|
|
|
|
190..199 'S::make()': (S<u32>, i32)
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_trait_assoc_method_generics_5() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait<T> {
|
|
|
|
fn make<U>() -> (Self, T, U);
|
|
|
|
}
|
|
|
|
struct S<T>;
|
|
|
|
impl Trait<i64> for S<u64> {}
|
|
|
|
fn test() {
|
|
|
|
let a = <S as Trait<i64>>::make::<u8>();
|
|
|
|
let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
106..210 '{ ...>(); }': ()
|
|
|
|
116..117 'a': (S<u64>, i64, u8)
|
|
|
|
120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
|
|
|
|
120..151 '<S as ...<u8>()': (S<u64>, i64, u8)
|
|
|
|
161..162 'b': (S<u64>, i64, u8)
|
|
|
|
181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
|
|
|
|
181..207 'Trait:...<u8>()': (S<u64>, i64, u8)
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_call_trait_method_on_generic_param_1() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait {
|
|
|
|
fn method(&self) -> u32;
|
|
|
|
}
|
|
|
|
fn test<T: Trait>(t: T) {
|
|
|
|
t.method();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
29..33 'self': &Self
|
|
|
|
63..64 't': T
|
|
|
|
69..88 '{ ...d(); }': ()
|
|
|
|
75..76 't': T
|
|
|
|
75..85 't.method()': u32
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_call_trait_method_on_generic_param_2() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Trait<T> {
|
|
|
|
fn method(&self) -> T;
|
|
|
|
}
|
|
|
|
fn test<U, T: Trait<U>>(t: T) {
|
|
|
|
t.method();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
32..36 'self': &Self
|
|
|
|
70..71 't': T
|
|
|
|
76..95 '{ ...d(); }': ()
|
|
|
|
82..83 't': T
|
|
|
|
82..92 't.method()': U
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn infer_with_multiple_trait_impls() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
trait Into<T> {
|
|
|
|
fn into(self) -> T;
|
|
|
|
}
|
|
|
|
struct S;
|
|
|
|
impl Into<u32> for S {}
|
|
|
|
impl Into<u64> for S {}
|
|
|
|
fn test() {
|
|
|
|
let x: u32 = S.into();
|
|
|
|
let y: u64 = S.into();
|
|
|
|
let z = Into::<u64>::into(S);
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
28..32 'self': Self
|
|
|
|
110..201 '{ ...(S); }': ()
|
|
|
|
120..121 'x': u32
|
|
|
|
129..130 'S': S
|
|
|
|
129..137 'S.into()': u32
|
|
|
|
147..148 'y': u64
|
|
|
|
156..157 'S': S
|
|
|
|
156..164 'S.into()': u64
|
|
|
|
174..175 'z': u64
|
|
|
|
178..195 'Into::...::into': fn into<S, u64>(S) -> u64
|
|
|
|
178..198 'Into::...nto(S)': u64
|
|
|
|
196..197 'S': S
|
|
|
|
"#]],
|
2019-12-03 12:38:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_unify_impl_self_type() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
struct S<T>;
|
2021-06-20 14:37:50 +00:00
|
|
|
impl S<u32> { fn foo(&self) -> u8 { 0 } }
|
|
|
|
impl S<i32> { fn foo(&self) -> i8 { 0 } }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (S::<u32>.foo(), S::<i32>.foo()); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (u8, i8)
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_trait_before_autoref() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl S { fn foo(&self) -> i8 { 0 } }
|
|
|
|
impl Trait for S { fn foo(self) -> u128 { 0 } }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { S.foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^ u128
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_by_value_before_autoref() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Clone { fn clone(&self) -> Self; }
|
|
|
|
struct S;
|
|
|
|
impl Clone for S {}
|
|
|
|
impl Clone for &S {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (S.clone(), (&S).clone(), (&&S).clone()); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (S, S, &S)
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_trait_before_autoderef() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl S { fn foo(self) -> i8 { 0 } }
|
|
|
|
impl Trait for &S { fn foo(self) -> u128 { 0 } }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (&S).foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^ u128
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_impl_before_trait() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl S { fn foo(self) -> i8 { 0 } }
|
|
|
|
impl Trait for S { fn foo(self) -> u128 { 0 } }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { S.foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^ i8
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_impl_ref_before_trait() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl S { fn foo(&self) -> i8 { 0 } }
|
|
|
|
impl Trait for &S { fn foo(self) -> u128 { 0 } }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { S.foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^ i8
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_trait_autoderef() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl Trait for S { fn foo(self) -> u128 { 0 } }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (&S).foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^ u128
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-02-29 21:01:36 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_unsize_array() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2020-02-29 21:01:36 +00:00
|
|
|
r#"
|
2021-06-15 18:34:26 +00:00
|
|
|
//- minicore: slice
|
2020-02-29 21:01:36 +00:00
|
|
|
fn test() {
|
|
|
|
let a = [1, 2, 3];
|
2020-06-29 15:22:47 +00:00
|
|
|
a.len();
|
2021-06-20 14:37:50 +00:00
|
|
|
} //^^^^^^^ usize
|
2020-02-29 21:01:36 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_trait_from_prelude() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
2021-06-01 11:39:19 +00:00
|
|
|
//- /main.rs crate:main deps:core
|
2019-12-03 12:38:54 +00:00
|
|
|
struct S;
|
|
|
|
impl Clone for S {}
|
|
|
|
|
|
|
|
fn test() {
|
2020-06-29 15:22:47 +00:00
|
|
|
S.clone();
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^ S
|
2019-12-03 12:38:54 +00:00
|
|
|
}
|
|
|
|
|
2021-06-01 11:39:19 +00:00
|
|
|
//- /lib.rs crate:core
|
|
|
|
pub mod prelude {
|
|
|
|
pub mod rust_2018 {
|
|
|
|
pub trait Clone {
|
|
|
|
fn clone(&self) -> Self;
|
|
|
|
}
|
2019-12-03 12:38:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_where_clause_for_unknown_trait() {
|
2019-12-21 14:00:44 +00:00
|
|
|
// The blanket impl currently applies because we ignore the unresolved where clause
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl<T> Trait for T where T: UnknownTrait {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (&S).foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^ u128
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_where_clause_not_met() {
|
|
|
|
// The blanket impl shouldn't apply because we can't prove S: Clone
|
2020-06-29 15:22:47 +00:00
|
|
|
// This is also to make sure that we don't resolve to the foo method just
|
|
|
|
// because that's the only method named foo we can find, which would make
|
|
|
|
// the below tests not work
|
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Clone {}
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl<T> Trait for T where T: Clone {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (&S).foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^ {unknown}
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_where_clause_inline_not_met() {
|
|
|
|
// The blanket impl shouldn't apply because we can't prove S: Clone
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Clone {}
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl<T: Clone> Trait for T {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (&S).foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^ {unknown}
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_where_clause_1() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Clone {}
|
|
|
|
trait Trait { fn foo(self) -> u128; }
|
|
|
|
struct S;
|
|
|
|
impl Clone for S {}
|
|
|
|
impl<T> Trait for T where T: Clone {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { S.foo(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^ u128
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_where_clause_2() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Into<T> { fn into(self) -> T; }
|
|
|
|
trait From<T> { fn from(other: T) -> Self; }
|
|
|
|
struct S1;
|
|
|
|
struct S2;
|
|
|
|
impl From<S2> for S1 {}
|
|
|
|
impl<T, U> Into<U> for T where U: From<T> {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { S2.into(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^ {unknown}
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_where_clause_inline() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait Into<T> { fn into(self) -> T; }
|
|
|
|
trait From<T> { fn from(other: T) -> Self; }
|
|
|
|
struct S1;
|
|
|
|
struct S2;
|
|
|
|
impl From<S2> for S1 {}
|
|
|
|
impl<T, U: From<T>> Into<U> for T {}
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { S2.into(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^ {unknown}
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-02-14 20:08:25 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_overloaded_method() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2020-02-14 20:08:25 +00:00
|
|
|
r#"
|
|
|
|
struct Wrapper<T>(T);
|
|
|
|
struct Foo<T>(T);
|
|
|
|
struct Bar<T>(T);
|
|
|
|
|
|
|
|
impl<T> Wrapper<Foo<T>> {
|
|
|
|
pub fn new(foo_: T) -> Self {
|
|
|
|
Wrapper(Foo(foo_))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Wrapper<Bar<T>> {
|
|
|
|
pub fn new(bar_: T) -> Self {
|
|
|
|
Wrapper(Bar(bar_))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let a = Wrapper::<Foo<f32>>::new(1.0);
|
|
|
|
let b = Wrapper::<Bar<f32>>::new(1.0);
|
2020-06-29 15:22:47 +00:00
|
|
|
(a, b);
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^ (Wrapper<Foo<f32>>, Wrapper<Bar<f32>>)
|
2020-02-14 20:08:25 +00:00
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-03-17 16:02:58 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_overloaded_const() {
|
|
|
|
cov_mark::check!(const_candidate_self_type_mismatch);
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
struct Wrapper<T>(T);
|
|
|
|
struct Foo<T>(T);
|
|
|
|
struct Bar<T>(T);
|
|
|
|
|
|
|
|
impl<T> Wrapper<Foo<T>> {
|
|
|
|
pub const VALUE: Foo<T>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Wrapper<Bar<T>> {
|
|
|
|
pub const VALUE: Bar<T>;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let a = Wrapper::<Foo<f32>>::VALUE;
|
|
|
|
let b = Wrapper::<Bar<f32>>::VALUE;
|
|
|
|
(a, b);
|
|
|
|
//^^^^^^ (Foo<f32>, Bar<f32>)
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_encountering_fn_type() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
//- /main.rs
|
|
|
|
fn foo() {}
|
|
|
|
trait FnOnce { fn call(self); }
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { foo.call(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^ {unknown}
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-21 17:17:06 +00:00
|
|
|
#[test]
|
|
|
|
fn super_trait_impl_return_trait_method_resolution() {
|
|
|
|
check_infer(
|
|
|
|
r#"
|
2021-06-15 22:23:04 +00:00
|
|
|
//- minicore: sized
|
2021-02-21 17:17:06 +00:00
|
|
|
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#"
|
2021-06-15 22:23:04 +00:00
|
|
|
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
|
2021-02-21 17:17:06 +00:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-02-18 11:26:00 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_non_parameter_type() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2020-02-18 11:26:00 +00:00
|
|
|
r#"
|
|
|
|
mod a {
|
|
|
|
pub trait Foo {
|
|
|
|
fn foo(&self);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Wrapper<T>(T);
|
|
|
|
fn foo<T>(t: Wrapper<T>)
|
|
|
|
where
|
|
|
|
Wrapper<T>: a::Foo,
|
|
|
|
{
|
2020-06-29 15:22:47 +00:00
|
|
|
t.foo();
|
2021-06-20 14:37:50 +00:00
|
|
|
} //^^^^^^^ {unknown}
|
2020-02-18 11:26:00 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-03-01 13:31:35 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_3373() {
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2020-03-01 13:31:35 +00:00
|
|
|
r#"
|
|
|
|
struct A<T>(T);
|
|
|
|
|
|
|
|
impl A<i32> {
|
|
|
|
fn from(v: i32) -> A<i32> { A(v) }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2020-06-29 15:22:47 +00:00
|
|
|
A::from(3);
|
2021-06-20 14:37:50 +00:00
|
|
|
} //^^^^^^^^^^ A<i32>
|
2020-03-01 13:31:35 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-03 12:38:54 +00:00
|
|
|
#[test]
|
|
|
|
fn method_resolution_slow() {
|
|
|
|
// this can get quite slow if we set the solver size limit too high
|
2020-06-29 15:22:47 +00:00
|
|
|
check_types(
|
2019-12-03 12:38:54 +00:00
|
|
|
r#"
|
|
|
|
trait SendX {}
|
|
|
|
|
|
|
|
struct S1; impl SendX for S1 {}
|
|
|
|
struct S2; impl SendX for S2 {}
|
|
|
|
struct U1;
|
|
|
|
|
|
|
|
trait Trait { fn method(self); }
|
|
|
|
|
|
|
|
struct X1<A, B> {}
|
|
|
|
impl<A, B> SendX for X1<A, B> where A: SendX, B: SendX {}
|
|
|
|
|
|
|
|
struct S<B, C> {}
|
|
|
|
|
|
|
|
trait FnX {}
|
|
|
|
|
|
|
|
impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {}
|
|
|
|
|
2020-06-29 15:22:47 +00:00
|
|
|
fn test() { (S {}).method(); }
|
2021-06-20 14:37:50 +00:00
|
|
|
//^^^^^^^^^^^^^^^ ()
|
2019-12-03 12:38:54 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2020-05-16 16:32:15 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dyn_trait_super_trait_not_in_scope() {
|
2020-07-21 10:08:55 +00:00
|
|
|
check_infer(
|
|
|
|
r#"
|
|
|
|
mod m {
|
|
|
|
pub trait SuperTrait {
|
|
|
|
fn foo(&self) -> u32 { 0 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
trait Trait: m::SuperTrait {}
|
|
|
|
|
|
|
|
struct S;
|
|
|
|
impl m::SuperTrait for S {}
|
|
|
|
impl Trait for S {}
|
|
|
|
|
|
|
|
fn test(d: &dyn Trait) {
|
|
|
|
d.foo();
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
51..55 'self': &Self
|
|
|
|
64..69 '{ 0 }': u32
|
|
|
|
66..67 '0': u32
|
|
|
|
176..177 'd': &dyn Trait
|
|
|
|
191..207 '{ ...o(); }': ()
|
|
|
|
197..198 'd': &dyn Trait
|
|
|
|
197..204 'd.foo()': u32
|
|
|
|
"#]],
|
2020-05-16 16:32:15 +00:00
|
|
|
);
|
|
|
|
}
|
2020-09-16 16:21:34 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_resolution_foreign_opaque_type() {
|
|
|
|
check_infer(
|
|
|
|
r#"
|
2021-09-26 09:12:57 +00:00
|
|
|
extern "C" {
|
|
|
|
type S;
|
|
|
|
fn f() -> &'static S;
|
|
|
|
}
|
2020-09-16 16:21:34 +00:00
|
|
|
|
2021-09-26 09:12:57 +00:00
|
|
|
impl S {
|
|
|
|
fn foo(&self) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
2020-09-16 16:21:34 +00:00
|
|
|
|
2021-09-26 09:12:57 +00:00
|
|
|
fn test() {
|
|
|
|
let s = unsafe { f() };
|
|
|
|
s.foo();
|
|
|
|
}
|
|
|
|
"#,
|
2020-09-16 16:21:34 +00:00
|
|
|
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
|
2021-09-26 09:12:57 +00:00
|
|
|
137..151 'unsafe { f() }': &S
|
2020-09-16 16:21:34 +00:00
|
|
|
146..147 'f': fn f() -> &S
|
|
|
|
146..149 'f()': &S
|
|
|
|
157..158 's': &S
|
2020-09-16 16:50:24 +00:00
|
|
|
157..164 's.foo()': bool
|
2020-09-16 16:21:34 +00:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2020-12-04 17:41:37 +00:00
|
|
|
|
|
|
|
#[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>;
|
2021-06-20 14:37:50 +00:00
|
|
|
foo.into_vec(); // we shouldn't crash on this at least
|
|
|
|
} //^^^^^^^^^^^^^^ {unknown}
|
2020-12-04 17:41:37 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2021-02-08 18:13:54 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn method_on_dyn_impl() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
trait Foo {}
|
|
|
|
|
|
|
|
impl Foo for u32 {}
|
2021-02-20 17:51:42 +00:00
|
|
|
impl dyn Foo + '_ {
|
2021-02-08 18:13:54 +00:00
|
|
|
pub fn dyn_foo(&self) -> u32 {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2021-02-20 17:51:42 +00:00
|
|
|
let f = &42u32 as &dyn Foo;
|
2021-02-08 18:13:54 +00:00
|
|
|
f.dyn_foo();
|
2021-06-20 14:37:50 +00:00
|
|
|
// ^^^^^^^^^^^ u32
|
2021-02-08 18:13:54 +00:00
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2021-03-20 16:13:58 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn autoderef_visibility_field() {
|
2021-07-09 17:12:56 +00:00
|
|
|
check(
|
2021-03-20 16:13:58 +00:00
|
|
|
r#"
|
2021-06-15 18:34:26 +00:00
|
|
|
//- minicore: deref
|
2021-03-20 16:13:58 +00:00
|
|
|
mod a {
|
|
|
|
pub struct Foo(pub char);
|
|
|
|
pub struct Bar(i32);
|
|
|
|
impl Bar {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Self(0)
|
|
|
|
}
|
|
|
|
}
|
2021-06-15 18:34:26 +00:00
|
|
|
impl core::ops::Deref for Bar {
|
2021-03-20 16:13:58 +00:00
|
|
|
type Target = Foo;
|
|
|
|
fn deref(&self) -> &Foo {
|
|
|
|
&Foo('z')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mod b {
|
|
|
|
fn foo() {
|
|
|
|
let x = super::a::Bar::new().0;
|
2021-07-09 17:12:56 +00:00
|
|
|
// ^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(Some(OverloadedDeref(Not)))
|
|
|
|
// ^^^^^^^^^^^^^^^^^^^^^^ type: char
|
2021-03-20 16:13:58 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-09 17:12:56 +00:00
|
|
|
"#,
|
2021-03-20 16:13:58 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn autoderef_visibility_method() {
|
2021-03-20 19:35:57 +00:00
|
|
|
cov_mark::check!(autoderef_candidate_not_visible);
|
2021-07-09 17:12:56 +00:00
|
|
|
check(
|
2021-03-20 16:13:58 +00:00
|
|
|
r#"
|
2021-06-15 18:36:50 +00:00
|
|
|
//- minicore: deref
|
2021-03-20 16:13:58 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2021-06-15 18:36:50 +00:00
|
|
|
impl core::ops::Deref for Bar {
|
2021-03-20 16:13:58 +00:00
|
|
|
type Target = Foo;
|
|
|
|
fn deref(&self) -> &Foo {
|
|
|
|
&Foo('z')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mod b {
|
|
|
|
fn foo() {
|
|
|
|
let x = super::a::Bar::new().mango();
|
2021-07-09 17:12:56 +00:00
|
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type: char
|
2021-03-20 16:13:58 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-09 17:12:56 +00:00
|
|
|
"#,
|
2021-03-20 16:13:58 +00:00
|
|
|
)
|
|
|
|
}
|
2021-04-07 01:33:22 +00:00
|
|
|
|
2022-03-17 16:02:58 +00:00
|
|
|
#[test]
|
|
|
|
fn trait_vs_private_inherent_const() {
|
|
|
|
cov_mark::check!(const_candidate_not_visible);
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
mod a {
|
|
|
|
pub struct Foo;
|
|
|
|
impl Foo {
|
|
|
|
const VALUE: u32 = 2;
|
|
|
|
}
|
|
|
|
pub trait Trait {
|
|
|
|
const VALUE: usize;
|
|
|
|
}
|
|
|
|
impl Trait for Foo {
|
|
|
|
const VALUE: usize = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn foo() {
|
|
|
|
let x = Foo::VALUE;
|
|
|
|
// ^^^^^^^^^^ type: u32
|
|
|
|
}
|
|
|
|
}
|
|
|
|
use a::Trait;
|
|
|
|
fn foo() {
|
|
|
|
let x = a::Foo::VALUE;
|
|
|
|
// ^^^^^^^^^^^^^ type: usize
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-04-07 01:33:22 +00:00
|
|
|
#[test]
|
2021-04-18 23:06:26 +00:00
|
|
|
fn trait_impl_in_unnamed_const() {
|
2021-04-07 01:33:22 +00:00
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
struct S;
|
|
|
|
|
|
|
|
trait Tr {
|
|
|
|
fn method(&self) -> u16;
|
|
|
|
}
|
|
|
|
|
|
|
|
const _: () = {
|
|
|
|
impl Tr for S {}
|
|
|
|
};
|
|
|
|
|
|
|
|
fn f() {
|
|
|
|
S.method();
|
|
|
|
//^^^^^^^^^^ u16
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2021-04-18 23:06:26 +00:00
|
|
|
|
2021-12-08 14:44:52 +00:00
|
|
|
#[test]
|
|
|
|
fn trait_impl_in_synstructure_const() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
struct S;
|
|
|
|
|
|
|
|
trait Tr {
|
|
|
|
fn method(&self) -> u16;
|
|
|
|
}
|
|
|
|
|
|
|
|
const _DERIVE_Tr_: () = {
|
|
|
|
impl Tr for S {}
|
|
|
|
};
|
|
|
|
|
|
|
|
fn f() {
|
|
|
|
S.method();
|
|
|
|
//^^^^^^^^^^ u16
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-04-18 23:06:26 +00:00
|
|
|
#[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
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2021-06-01 19:33:14 +00:00
|
|
|
|
2021-09-08 08:00:55 +00:00
|
|
|
#[test]
|
|
|
|
fn resolve_const_generic_array_methods() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
#[lang = "array"]
|
|
|
|
impl<T, const N: usize> [T; N] {
|
|
|
|
pub fn map<F, U>(self, f: F) -> [U; N]
|
|
|
|
where
|
|
|
|
F: FnMut(T) -> U,
|
|
|
|
{ loop {} }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[lang = "slice"]
|
|
|
|
impl<T> [T] {
|
|
|
|
pub fn map<F, U>(self, f: F) -> &[U]
|
|
|
|
where
|
|
|
|
F: FnMut(T) -> U,
|
|
|
|
{ loop {} }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn f() {
|
|
|
|
let v = [1, 2].map::<_, usize>(|x| -> x * 2);
|
|
|
|
v;
|
2022-03-09 18:50:24 +00:00
|
|
|
//^ [usize; 2]
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn resolve_const_generic_method() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
struct Const<const N: usize>;
|
|
|
|
|
|
|
|
#[lang = "array"]
|
|
|
|
impl<T, const N: usize> [T; N] {
|
|
|
|
pub fn my_map<F, U, const X: usize>(self, f: F, c: Const<X>) -> [U; X]
|
|
|
|
where
|
|
|
|
F: FnMut(T) -> U,
|
|
|
|
{ loop {} }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[lang = "slice"]
|
|
|
|
impl<T> [T] {
|
|
|
|
pub fn my_map<F, const X: usize, U>(self, f: F, c: Const<X>) -> &[U]
|
|
|
|
where
|
|
|
|
F: FnMut(T) -> U,
|
|
|
|
{ loop {} }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn f<const C: usize, P>() {
|
|
|
|
let v = [1, 2].my_map::<_, (), 12>(|x| -> x * 2, Const::<12>);
|
|
|
|
v;
|
|
|
|
//^ [(); 12]
|
|
|
|
let v = [1, 2].my_map::<_, P, C>(|x| -> x * 2, Const::<C>);
|
|
|
|
v;
|
|
|
|
//^ [P; C]
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn const_generic_type_alias() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
struct Const<const N: usize>;
|
|
|
|
type U2 = Const<2>;
|
|
|
|
type U5 = Const<5>;
|
|
|
|
|
|
|
|
impl U2 {
|
|
|
|
fn f(self) -> Const<12> {
|
|
|
|
loop {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl U5 {
|
|
|
|
fn f(self) -> Const<15> {
|
|
|
|
loop {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn f(x: U2) {
|
|
|
|
let y = x.f();
|
|
|
|
//^ Const<12>
|
2021-09-08 08:00:55 +00:00
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-06-01 19:33:14 +00:00
|
|
|
#[test]
|
|
|
|
fn skip_array_during_method_dispatch() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
//- /main2018.rs crate:main2018 deps:core
|
|
|
|
use core::IntoIterator;
|
|
|
|
|
|
|
|
fn f() {
|
|
|
|
let v = [4].into_iter();
|
|
|
|
v;
|
|
|
|
//^ &i32
|
|
|
|
|
|
|
|
let a = [0, 1].into_iter();
|
|
|
|
a;
|
|
|
|
//^ &i32
|
|
|
|
}
|
|
|
|
|
|
|
|
//- /main2021.rs crate:main2021 deps:core edition:2021
|
|
|
|
use core::IntoIterator;
|
|
|
|
|
|
|
|
fn f() {
|
|
|
|
let v = [4].into_iter();
|
|
|
|
v;
|
|
|
|
//^ i32
|
|
|
|
|
|
|
|
let a = [0, 1].into_iter();
|
|
|
|
a;
|
|
|
|
//^ &i32
|
|
|
|
}
|
|
|
|
|
|
|
|
//- /core.rs crate:core
|
|
|
|
#[rustc_skip_array_during_method_dispatch]
|
|
|
|
pub trait IntoIterator {
|
|
|
|
type Out;
|
|
|
|
fn into_iter(self) -> Self::Out;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> IntoIterator for [T; 1] {
|
|
|
|
type Out = T;
|
2021-06-20 14:37:50 +00:00
|
|
|
fn into_iter(self) -> Self::Out { loop {} }
|
2021-06-01 19:33:14 +00:00
|
|
|
}
|
|
|
|
impl<'a, T> IntoIterator for &'a [T] {
|
|
|
|
type Out = &'a T;
|
2021-06-20 14:37:50 +00:00
|
|
|
fn into_iter(self) -> Self::Out { loop {} }
|
2021-06-01 19:33:14 +00:00
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2021-06-12 16:47:07 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn sized_blanket_impl() {
|
|
|
|
check_infer(
|
|
|
|
r#"
|
2021-06-15 22:23:04 +00:00
|
|
|
//- minicore: sized
|
2021-06-12 16:47:07 +00:00
|
|
|
trait Foo { fn foo() -> u8; }
|
|
|
|
impl<T: Sized> Foo for T {}
|
|
|
|
fn f<S: Sized, T, U: ?Sized>() {
|
|
|
|
u32::foo;
|
|
|
|
S::foo;
|
|
|
|
T::foo;
|
|
|
|
U::foo;
|
|
|
|
<[u32]>::foo;
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2021-06-15 22:23:04 +00:00
|
|
|
89..160 '{ ...foo; }': ()
|
|
|
|
95..103 'u32::foo': fn foo<u32>() -> u8
|
|
|
|
109..115 'S::foo': fn foo<S>() -> u8
|
|
|
|
121..127 'T::foo': fn foo<T>() -> u8
|
|
|
|
133..139 'U::foo': {unknown}
|
|
|
|
145..157 '<[u32]>::foo': {unknown}
|
2021-06-12 16:47:07 +00:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2021-11-09 10:13:42 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn local_impl() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
fn main() {
|
|
|
|
struct SomeStruct(i32);
|
|
|
|
|
|
|
|
impl SomeStruct {
|
|
|
|
fn is_even(&self) -> bool {
|
|
|
|
self.0 % 2 == 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let o = SomeStruct(3);
|
|
|
|
let is_even = o.is_even();
|
|
|
|
// ^^^^^^^ bool
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2021-09-05 14:40:46 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn deref_fun_1() {
|
Refactor autoderef and method resolution
- don't return the receiver type from method resolution; instead just
return the autorefs/autoderefs that happened and repeat them. This
ensures all the effects like trait obligations and whatever we learned
about type variables from derefing them are actually applied. Also, it
allows us to get rid of `decanonicalize_ty`, which was just wrong in
principle.
- Autoderef itself now directly works with an inference table. Sadly
this has the effect of making it harder to use as an iterator, often
requiring manual `while let` loops. (rustc works around this by using
inner mutability in the inference context, so that things like unifying
types don't require a unique reference.)
- We now record the adjustments (autoref/deref) for method receivers
and index expressions, which we didn't before.
- Removed the redundant crate parameter from method resolution, since
the trait_env contains the crate as well.
- in the HIR API, the methods now take a scope to determine the trait env.
`Type` carries a trait env, but I think that's probably a bad decision
because it's easy to create it with the wrong env, e.g. by using
`Adt::ty`. This mostly didn't matter so far because
`iterate_method_candidates` took a crate parameter and ignored
`self.krate`, but the trait env would still have been wrong in those
cases, which I think would give some wrong results in some edge cases.
Fixes #10058.
2022-02-16 16:44:03 +00:00
|
|
|
check_types(
|
|
|
|
r#"
|
2021-09-05 14:40:46 +00:00
|
|
|
//- minicore: deref
|
|
|
|
|
|
|
|
struct A<T, U>(T, U);
|
|
|
|
struct B<T>(T);
|
|
|
|
struct C<T>(T);
|
|
|
|
|
|
|
|
impl<T> core::ops::Deref for A<B<T>, u32> {
|
|
|
|
type Target = B<T>;
|
|
|
|
fn deref(&self) -> &B<T> { &self.0 }
|
|
|
|
}
|
|
|
|
impl core::ops::Deref for B<isize> {
|
|
|
|
type Target = C<isize>;
|
|
|
|
fn deref(&self) -> &C<isize> { loop {} }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Copy> C<T> {
|
|
|
|
fn thing(&self) -> T { self.0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn make<T>() -> T { loop {} }
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let a1 = A(make(), make());
|
|
|
|
let _: usize = (*a1).0;
|
|
|
|
a1;
|
|
|
|
//^^ A<B<usize>, u32>
|
|
|
|
|
|
|
|
let a2 = A(make(), make());
|
|
|
|
a2.thing();
|
|
|
|
//^^^^^^^^^^ isize
|
|
|
|
a2;
|
|
|
|
//^^ A<B<isize>, u32>
|
|
|
|
}
|
Refactor autoderef and method resolution
- don't return the receiver type from method resolution; instead just
return the autorefs/autoderefs that happened and repeat them. This
ensures all the effects like trait obligations and whatever we learned
about type variables from derefing them are actually applied. Also, it
allows us to get rid of `decanonicalize_ty`, which was just wrong in
principle.
- Autoderef itself now directly works with an inference table. Sadly
this has the effect of making it harder to use as an iterator, often
requiring manual `while let` loops. (rustc works around this by using
inner mutability in the inference context, so that things like unifying
types don't require a unique reference.)
- We now record the adjustments (autoref/deref) for method receivers
and index expressions, which we didn't before.
- Removed the redundant crate parameter from method resolution, since
the trait_env contains the crate as well.
- in the HIR API, the methods now take a scope to determine the trait env.
`Type` carries a trait env, but I think that's probably a bad decision
because it's easy to create it with the wrong env, e.g. by using
`Adt::ty`. This mostly didn't matter so far because
`iterate_method_candidates` took a crate parameter and ignored
`self.krate`, but the trait env would still have been wrong in those
cases, which I think would give some wrong results in some edge cases.
Fixes #10058.
2022-02-16 16:44:03 +00:00
|
|
|
"#,
|
|
|
|
);
|
2021-09-05 14:40:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn deref_fun_2() {
|
Refactor autoderef and method resolution
- don't return the receiver type from method resolution; instead just
return the autorefs/autoderefs that happened and repeat them. This
ensures all the effects like trait obligations and whatever we learned
about type variables from derefing them are actually applied. Also, it
allows us to get rid of `decanonicalize_ty`, which was just wrong in
principle.
- Autoderef itself now directly works with an inference table. Sadly
this has the effect of making it harder to use as an iterator, often
requiring manual `while let` loops. (rustc works around this by using
inner mutability in the inference context, so that things like unifying
types don't require a unique reference.)
- We now record the adjustments (autoref/deref) for method receivers
and index expressions, which we didn't before.
- Removed the redundant crate parameter from method resolution, since
the trait_env contains the crate as well.
- in the HIR API, the methods now take a scope to determine the trait env.
`Type` carries a trait env, but I think that's probably a bad decision
because it's easy to create it with the wrong env, e.g. by using
`Adt::ty`. This mostly didn't matter so far because
`iterate_method_candidates` took a crate parameter and ignored
`self.krate`, but the trait env would still have been wrong in those
cases, which I think would give some wrong results in some edge cases.
Fixes #10058.
2022-02-16 16:44:03 +00:00
|
|
|
check_types(
|
|
|
|
r#"
|
2021-09-05 14:40:46 +00:00
|
|
|
//- minicore: deref
|
|
|
|
|
|
|
|
struct A<T, U>(T, U);
|
|
|
|
struct B<T>(T);
|
|
|
|
struct C<T>(T);
|
|
|
|
|
|
|
|
impl<T> core::ops::Deref for A<B<T>, u32> {
|
|
|
|
type Target = B<T>;
|
|
|
|
fn deref(&self) -> &B<T> { &self.0 }
|
|
|
|
}
|
|
|
|
impl core::ops::Deref for B<isize> {
|
|
|
|
type Target = C<isize>;
|
|
|
|
fn deref(&self) -> &C<isize> { loop {} }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> core::ops::Deref for A<C<T>, i32> {
|
|
|
|
type Target = C<T>;
|
|
|
|
fn deref(&self) -> &C<T> { &self.0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Copy> C<T> {
|
|
|
|
fn thing(&self) -> T { self.0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn make<T>() -> T { loop {} }
|
|
|
|
|
|
|
|
fn test() {
|
|
|
|
let a1 = A(make(), 1u32);
|
|
|
|
a1.thing();
|
|
|
|
a1;
|
|
|
|
//^^ A<B<isize>, u32>
|
|
|
|
|
|
|
|
let a2 = A(make(), 1i32);
|
|
|
|
let _: &str = a2.thing();
|
|
|
|
a2;
|
|
|
|
//^^ A<C<&str>, i32>
|
|
|
|
}
|
Refactor autoderef and method resolution
- don't return the receiver type from method resolution; instead just
return the autorefs/autoderefs that happened and repeat them. This
ensures all the effects like trait obligations and whatever we learned
about type variables from derefing them are actually applied. Also, it
allows us to get rid of `decanonicalize_ty`, which was just wrong in
principle.
- Autoderef itself now directly works with an inference table. Sadly
this has the effect of making it harder to use as an iterator, often
requiring manual `while let` loops. (rustc works around this by using
inner mutability in the inference context, so that things like unifying
types don't require a unique reference.)
- We now record the adjustments (autoref/deref) for method receivers
and index expressions, which we didn't before.
- Removed the redundant crate parameter from method resolution, since
the trait_env contains the crate as well.
- in the HIR API, the methods now take a scope to determine the trait env.
`Type` carries a trait env, but I think that's probably a bad decision
because it's easy to create it with the wrong env, e.g. by using
`Adt::ty`. This mostly didn't matter so far because
`iterate_method_candidates` took a crate parameter and ignored
`self.krate`, but the trait env would still have been wrong in those
cases, which I think would give some wrong results in some edge cases.
Fixes #10058.
2022-02-16 16:44:03 +00:00
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn receiver_adjustment_autoref() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct Foo;
|
|
|
|
impl Foo {
|
|
|
|
fn foo(&self) {}
|
|
|
|
}
|
|
|
|
fn test() {
|
|
|
|
Foo.foo();
|
|
|
|
//^^^ adjustments: Borrow(Ref(Not))
|
|
|
|
(&Foo).foo();
|
|
|
|
// ^^^^ adjustments: ,
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn receiver_adjustment_unsize_array() {
|
|
|
|
// FIXME not quite correct
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
//- minicore: slice
|
|
|
|
fn test() {
|
|
|
|
let a = [1, 2, 3];
|
|
|
|
a.len();
|
|
|
|
} //^ adjustments: Pointer(Unsize), Borrow(Ref(Not))
|
|
|
|
"#,
|
|
|
|
);
|
2021-09-05 14:40:46 +00:00
|
|
|
}
|
2022-03-23 18:18:12 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bad_inferred_reference_1() {
|
|
|
|
check_no_mismatches(
|
|
|
|
r#"
|
|
|
|
//- minicore: sized
|
|
|
|
pub trait Into<T>: Sized {
|
|
|
|
fn into(self) -> T;
|
|
|
|
}
|
|
|
|
impl<T> Into<T> for T {
|
|
|
|
fn into(self) -> T { self }
|
|
|
|
}
|
|
|
|
|
|
|
|
trait ExactSizeIterator {
|
|
|
|
fn len(&self) -> usize;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Foo;
|
|
|
|
impl Foo {
|
|
|
|
fn len(&self) -> usize { 0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn test(generic_args: impl Into<Foo>) {
|
|
|
|
let generic_args = generic_args.into();
|
|
|
|
generic_args.len();
|
|
|
|
let _: Foo = generic_args;
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bad_inferred_reference_2() {
|
|
|
|
check_no_mismatches(
|
|
|
|
r#"
|
|
|
|
//- minicore: deref
|
|
|
|
trait ExactSizeIterator {
|
|
|
|
fn len(&self) -> usize;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Foo;
|
|
|
|
impl Foo {
|
|
|
|
fn len(&self) -> usize { 0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn test() {
|
|
|
|
let generic_args;
|
|
|
|
generic_args.len();
|
|
|
|
let _: Foo = generic_args;
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2022-03-23 18:47:11 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn resolve_minicore_iterator() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
//- minicore: iterators, sized
|
|
|
|
fn foo() {
|
|
|
|
let m = core::iter::repeat(()).filter_map(|()| Some(92)).next();
|
|
|
|
} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Option<i32>
|
|
|
|
"#,
|
|
|
|
);
|
|
|
|
}
|
2022-04-14 13:51:38 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn primitive_assoc_fn_shadowed_by_use() {
|
|
|
|
check_types(
|
|
|
|
r#"
|
|
|
|
//- /lib.rs crate:lib deps:core
|
|
|
|
use core::u16;
|
|
|
|
|
|
|
|
fn f() -> u16 {
|
|
|
|
let x = u16::from_le_bytes();
|
|
|
|
x
|
|
|
|
//^ u16
|
|
|
|
}
|
|
|
|
|
|
|
|
//- /core.rs crate:core
|
|
|
|
pub mod u16 {}
|
|
|
|
|
|
|
|
impl u16 {
|
|
|
|
pub fn from_le_bytes() -> Self { 0 }
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
}
|